{"_id":"@metrichor/epi2me-api","_rev":"235-70751cd01def82dafa8c325fc51b8130","time":{"2019.11.18-1010":"2019-11-19T14:27:27.344Z","2019.11.19-1328":"2019-11-19T14:27:27.344Z","created":"2019-11-19T15:10:56.308Z","3.0.1510":"2019-11-19T15:10:56.433Z","modified":"2023-07-27T16:36:48.144Z","3.0.2946377":"2019-11-19T15:30:48.673Z","3.0.2996439":"2019-12-03T15:11:08.475Z","3.0.3010186":"2019-12-06T17:18:53.134Z","3.0.3014799":"2019-12-09T17:12:40.292Z","3.0.3020472":"2019-12-10T17:19:25.318Z","3.0.3025991":"2019-12-11T19:44:24.532Z","3.0.3090503":"2020-01-09T13:46:44.094Z","3.0.3182029":"2020-02-06T16:09:57.605Z","3.0.3187188":"2020-02-07T17:13:09.901Z","3.0.3339019":"2020-03-16T15:38:12.156Z","3.0.3683829":"2020-06-03T15:38:31.182Z","4.0.4117339":"2020-09-14T13:18:06.236Z","4.0.4117465":"2020-09-14T13:44:17.364Z","4.0.4117484":"2020-09-14T13:53:25.925Z","4.0.4117520":"2020-09-14T14:02:13.506Z","4.0.4118002":"2020-09-14T15:10:11.999Z","4.0.4118479":"2020-09-14T16:33:58.118Z","4.0.4118528":"2020-09-14T16:59:37.441Z","4.0.4120169":"2020-09-15T09:24:13.127Z","4.0.4120508":"2020-09-15T10:04:37.194Z","4.0.4120778":"2020-09-15T10:29:44.333Z","4.0.4120935":"2020-09-15T10:43:15.645Z","4.0.4121231":"2020-09-15T11:16:09.331Z","4.0.4122305":"2020-09-15T13:35:45.221Z","4.0.4123252":"2020-09-15T15:07:44.016Z","4.0.4124924":"2020-09-15T20:27:55.642Z","4.0.4126560":"2020-09-16T09:10:06.799Z","4.0.4126815":"2020-09-16T09:48:47.393Z","4.0.4126910":"2020-09-16T10:05:15.893Z","4.0.4127000":"2020-09-16T10:18:46.016Z","4.0.4127128":"2020-09-16T10:36:21.133Z","4.0.4127700":"2020-09-16T11:50:27.313Z","4.0.4129621":"2020-09-16T13:58:58.459Z","4.0.4131210":"2020-09-16T16:19:14.868Z","4.0.4138326":"2020-09-17T15:28:08.355Z","4.0.4138613":"2020-09-17T16:12:31.966Z","4.0.4138732":"2020-09-17T16:39:50.061Z","4.0.4139980":"2020-09-18T05:48:51.153Z","4.0.4144912":"2020-09-18T16:26:49.536Z","4.0.4144909":"2020-09-18T16:27:21.193Z","4.0.4144922":"2020-09-18T16:32:41.144Z","4.0.4149450":"2020-09-21T09:05:57.264Z","4.0.4152828":"2020-09-21T15:34:02.902Z","4.0.4153188":"2020-09-21T16:37:01.977Z","4.0.4153687":"2020-09-21T21:47:41.637Z","4.0.4153945":"2020-09-21T21:54:16.061Z","4.0.4167526":"2020-09-24T08:45:29.358Z","4.0.4167529":"2020-09-24T08:59:32.434Z","4.0.4167714":"2020-09-24T09:07:36.677Z","4.0.4177170":"2020-09-25T14:18:28.014Z","4.0.4177343":"2020-09-25T14:41:22.141Z","4.0.4186216":"2020-09-28T18:10:38.040Z","4.0.4201189":"2020-10-02T08:53:25.653Z","4.0.4201911":"2020-10-02T11:30:07.202Z","4.0.4202172":"2020-10-02T12:39:06.942Z","4.0.4204100":"2020-10-02T16:14:59.178Z","4.0.4207813":"2020-10-05T09:56:00.068Z","4.0.4208387":"2020-10-05T10:02:10.335Z","4.0.4222914":"2020-10-07T16:30:58.036Z","4.0.4222982":"2020-10-07T16:40:09.540Z","4.0.4245019":"2020-10-13T11:07:19.078Z","4.0.4246970":"2020-10-13T15:55:50.944Z","4.0.4247642":"2020-10-13T16:25:32.610Z","4.0.4251160":"2020-10-14T16:16:49.673Z","4.0.4251193":"2020-10-14T16:22:47.206Z","4.0.4253933":"2020-10-15T12:13:26.673Z","4.0.4256044":"2020-10-15T16:15:43.317Z","4.0.4316294":"2020-10-30T14:33:32.476Z","4.0.4317827":"2020-10-30T18:22:36.695Z","4.0.4323692":"2020-11-03T09:27:13.363Z","4.0.4324944":"2020-11-03T09:33:40.630Z","4.0.4331115":"2020-11-04T10:12:39.293Z","4.0.4331484":"2020-11-04T10:43:50.772Z","4.0.4366893":"2020-11-13T14:36:33.093Z","4.0.4383100":"2020-11-18T14:08:03.602Z","4.0.4394830":"2020-11-23T09:45:46.124Z","4.0.4396058":"2020-11-23T12:31:38.361Z","4.0.4396062":"2020-11-23T12:32:36.880Z","4.0.4433300":"2020-11-30T15:39:51.304Z","4.0.4438332":"2020-12-01T15:16:14.033Z","4.0.4438536":"2020-12-01T15:24:00.018Z","4.0.4438881":"2020-12-01T17:17:13.399Z","4.0.4456258":"2020-12-04T16:49:23.710Z","4.0.4456738":"2020-12-04T17:32:39.759Z","4.0.4460253":"2020-12-07T10:37:22.275Z","4.0.4466780":"2020-12-08T15:52:12.550Z","4.0.4467680":"2020-12-08T17:19:55.505Z","4.0.4467990":"2020-12-08T17:46:29.286Z","4.0.4481265":"2020-12-10T18:11:20.819Z","4.0.4486532":"2020-12-11T16:58:46.306Z","4.0.4491868":"2020-12-14T15:16:29.519Z","4.0.4492416":"2020-12-14T15:35:13.238Z","4.0.4492990":"2020-12-14T16:54:35.870Z","4.0.4564472":"2021-01-05T13:57:53.927Z","4.0.4580325":"2021-01-07T15:38:09.143Z","4.0.4602916":"2021-01-13T10:05:57.011Z","4.0.4603198":"2021-01-13T10:38:47.494Z","4.0.4604391":"2021-01-13T12:25:47.486Z","4.0.4703121":"2021-01-29T18:46:51.970Z","4.0.4798116":"2021-02-17T15:11:18.793Z","4.0.4799240":"2021-02-17T18:02:10.642Z","4.0.4799307":"2021-02-17T18:12:15.863Z","4.0.4799343":"2021-02-17T18:16:54.368Z","4.0.4824500":"2021-02-23T09:46:14.566Z","4.0.4829096":"2021-02-23T15:19:07.385Z","4.0.4830031":"2021-02-23T16:44:06.196Z","4.0.4842297":"2021-02-25T11:25:04.731Z","4.0.4848715":"2021-02-26T11:05:10.105Z","4.0.4848863":"2021-02-26T11:21:41.572Z","4.0.4848923":"2021-02-26T11:43:29.488Z","5.0.4859830":"2021-03-01T15:56:54.424Z","5.0.4876842":"2021-03-03T15:39:22.918Z","5.0.4927889":"2021-03-11T16:12:22.195Z","5.0.4961252":"2021-03-17T18:02:31.333Z","5.0.4969466":"2021-03-18T18:26:00.296Z","5.0.4988301":"2021-03-22T17:57:26.070Z","5.0.5098713":"2021-04-13T16:23:30.013Z","5.0.5156024":"2021-04-22T15:14:34.636Z","5.0.5185212":"2021-04-28T12:08:17.185Z","5.0.5200121":"2021-04-30T16:42:15.947Z","5.0.5353744":"2021-05-27T13:32:56.856Z","5.0.5357219":"2021-05-27T16:57:13.649Z","5.0.5360735":"2021-05-28T11:40:12.049Z","5.0.5363006":"2021-05-28T16:23:39.160Z","5.0.5386988":"2021-06-03T17:55:09.354Z","5.0.5404269":"2021-06-08T08:13:07.977Z","5.0.5417264":"2021-06-09T12:22:11.487Z","5.0.5417268":"2021-06-09T12:24:45.892Z","5.0.5417588":"2021-06-09T13:10:55.056Z","5.0.5596806":"2021-07-12T10:07:33.565Z","5.0.5605714":"2021-07-13T10:46:50.478Z","5.0.5605910":"2021-07-13T10:54:56.119Z","5.1.5612995":"2021-07-14T13:26:23.383Z","5.1.5622563":"2021-07-16T08:29:20.991Z","5.1.5624711":"2021-07-16T13:47:37.918Z","5.1.5638463":"2021-07-20T11:22:42.764Z","5.1.5638553":"2021-07-20T11:44:16.864Z","5.1.5641372":"2021-07-20T17:10:05.658Z","5.1.5641422":"2021-07-20T17:25:18.378Z","5.1.5691392":"2021-07-30T14:14:06.222Z","5.1.5709981":"2021-08-04T09:22:06.406Z","5.1.5719574":"2021-08-05T12:01:16.047Z","5.1.5721326":"2021-08-05T15:13:07.230Z","5.1.5721635":"2021-08-05T16:03:53.057Z","5.1.5740035":"2021-08-10T11:41:06.320Z","5.1.5765192":"2021-08-13T17:53:52.715Z","5.1.5778872":"2021-08-17T15:42:47.868Z","5.1.5779009":"2021-08-17T16:04:54.005Z","5.1.5779035":"2021-08-17T16:05:47.474Z","5.1.5780952":"2021-08-17T20:44:37.437Z","5.1.5813039":"2021-08-24T14:33:22.900Z","5.1.5813271":"2021-08-24T14:40:39.455Z","5.1.5821051":"2021-08-25T16:46:06.324Z","5.1.5875795":"2021-09-07T09:03:06.583Z","5.1.5881112":"2021-09-07T18:20:14.094Z","5.1.5910440":"2021-09-13T17:22:29.326Z","5.1.5912653":"2021-09-14T08:30:06.597Z","5.1.5926490":"2021-09-16T10:37:41.912Z","5.1.6001567":"2021-09-28T15:45:51.016Z","5.1.6028772":"2021-10-01T15:23:24.438Z","5.1.6058802":"2021-10-06T14:54:31.010Z","5.1.6089496":"2021-10-12T17:29:02.552Z","5.1.6089492":"2021-10-12T17:29:06.046Z","5.1.6099804":"2021-10-14T09:00:26.545Z","5.1.6269660":"2021-11-16T15:06:53.972Z","5.1.6338234":"2021-11-26T13:05:35.356Z","6.0.6356455":"2021-11-30T12:27:46.197Z","6.0.6359806":"2021-11-30T16:52:24.650Z","5.1.6380181":"2021-12-03T10:02:54.917Z","6.0.6390813":"2021-12-06T15:44:02.818Z","6.0.6398206":"2021-12-07T17:37:18.679Z","6.0.6398535":"2021-12-07T18:27:44.926Z","6.0.6403726":"2021-12-09T12:17:48.460Z","6.0.6412072":"2021-12-09T15:02:54.333Z","6.0.6532891":"2022-01-05T17:34:04.252Z","6.0.6532936":"2022-01-05T17:40:44.585Z","6.0.6905467":"2022-02-09T14:04:47.823Z","6.0.6966242":"2022-02-15T11:18:02.268Z","6.0.6970419":"2022-02-15T16:10:08.587Z","6.0.7043994":"2022-02-22T17:05:59.674Z","6.0.7044474":"2022-02-22T18:07:23.731Z","6.0.7044626":"2022-02-22T18:13:41.861Z","6.0.7044649":"2022-02-22T18:18:42.947Z","6.0.7103694":"2022-02-28T17:49:53.758Z","6.0.7149896":"2022-03-04T12:12:52.333Z","6.0.7173308":"2022-03-07T15:46:05.691Z","6.0.7174788":"2022-03-07T15:56:06.445Z","6.0.7176693":"2022-03-07T18:12:59.876Z","6.0.7183600":"2022-03-08T12:07:35.668Z","6.0.7292964":"2022-03-18T10:42:13.670Z","6.0.7298596":"2022-03-18T16:33:20.983Z","6.0.7299067":"2022-03-18T17:04:11.844Z","6.0.7339081":"2022-03-23T09:46:51.217Z","6.0.7346771":"2022-03-23T18:19:47.982Z","6.0.7346926":"2022-03-24T10:02:30.362Z","6.0.7408877":"2022-03-29T16:25:51.847Z","6.0.7476504":"2022-04-05T09:51:31.225Z","6.0.7479716":"2022-04-05T13:45:43.902Z","6.0.7581324":"2022-04-19T09:40:04.435Z","6.0.7611483":"2022-04-19T09:50:43.066Z","6.1.7810599":"2022-05-09T17:25:07.202Z","6.1.7810647":"2022-05-09T17:35:01.749Z","7.0.7811028":"2022-05-09T18:25:30.122Z","6.1.7893410":"2022-05-17T09:54:50.671Z","7.0.7893911":"2022-05-17T10:39:00.799Z","7.0.7974668":"2022-05-24T09:09:33.036Z","7.0.7975370":"2022-05-24T09:47:35.787Z","7.0.8286949":"2022-06-22T09:31:31.092Z","7.0.8293283":"2022-06-22T15:26:53.753Z","7.0.8293242":"2022-06-22T16:18:54.038Z","7.0.8400083":"2022-07-01T13:57:09.822Z","7.1.8860292":"2022-08-24T14:31:28.047Z","7.1.8934394":"2022-09-06T13:11:32.733Z","7.1.8949394":"2022-09-08T08:33:02.437Z","7.1.8949620":"2022-09-08T08:58:28.058Z","7.1.9018732":"2022-09-20T15:53:19.310Z","7.1.9018737":"2022-09-20T15:53:29.034Z","7.2.9018966":"2022-09-21T08:15:16.611Z","7.2.9021389":"2022-09-21T08:21:39.344Z","7.2.9057104":"2022-09-27T10:31:08.495Z","7.2.9453780":"2022-11-22T14:06:23.303Z","7.2.10180649":"2023-02-28T16:42:35.830Z","7.2.10218934":"2023-03-03T13:09:56.940Z","7.2.10393877":"2023-03-21T18:49:31.604Z","7.2.10405862":"2023-03-22T18:05:10.149Z","7.2.11907093":"2023-07-25T09:49:26.722Z","7.3.11924383":"2023-07-26T10:56:52.695Z","7.3.11924827":"2023-07-26T11:19:28.558Z","7.3.11957764":"2023-07-27T16:33:20.499Z","7.3.11957861":"2023-07-27T16:36:47.867Z"},"name":"@metrichor/epi2me-api","dist-tags":{"latest":"6.1.7893410","experimental":"7.3.11957764","develop":"7.3.11957861","next":"7.3.11924827"},"versions":{"3.0.1510":{"name":"@metrichor/epi2me-api","version":"3.0.1510","license":"MPL-2.0","repository":{"type":"git","url":"https://git.oxfordnanolabs.local/metrichor/api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.1","@types/axios":"^0.14.0","apollo-cache-inmemory":"^1.6.3","apollo-client":"^2.6.4","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.574.0","axios":"^0.19.0","core-js":"^3.2.1","fs-extra":"^8.1.0","graphql":"^14.5.8","graphql-tag":"^2.10.1","lodash":"4.17.15","proxy-agent":"^3.1.1","save":"^2.4.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.6.2","@babel/core":"^7.6.2","@babel/plugin-proposal-object-rest-spread":"^7.6.2","@babel/preset-env":"^7.6.2","@babel/register":"^7.6.2","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"6.6.0","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-import":"^2.18.2","eslint-plugin-prettier":"^3.1.1","husky":"^3.0.8","lint-staged":"^9.4.2","mocha":"6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.27.2","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.12.1","rollup-plugin-terser":"^5.1.2","sinon":"7.5.0","tmp":"0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"npx mocha --recursive --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"2884b1f8e83f03f07a637eb8b467b176f3bb6571","_id":"@metrichor/epi2me-api@3.0.1510","_npmVersion":"6.4.1","_nodeVersion":"8.16.2","_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"dist":{"integrity":"sha512-w/uiQKJcSKvR5zTxQ68RrbNb7mmbQJCdYI/UE/Gf7vINeSGu/gRuWDOxJTwSj6VTN4OeDf486vtUNbZDA8Optg==","shasum":"6563938ddc294ec8206f5ea19a7845d55d9d4a10","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.1510.tgz","fileCount":118,"unpackedSize":554571,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd1AYACRA9TVsSAnZWagAAsb0P/RlG4zvdfPSPD3+jvNiN\nJaKidz9oUEcPqu3xQMu9oXGqekX+8z3ma/WBtvv8AxFXMHDcHA25GVT7Wdxm\nYJe4HrVXaHzkh+Xk/PfAQXKAkn76erjoWRsKy74Nu/r+KaXZm1Y2VxYBkTFk\nvIYcWUBI4qsJToIgEkz3F/dK3Nhnz5z/jnnhE7YPvy/griKLEcsIWtH8SAyu\ntDxzVKtbOtJ0As+/kdHd1hwkzYle9JIjqbhVP+P9Nauy16HWfDg6oSd2Jqsx\nD+J+cQx96GdQ5bS5J+Yb/1iKzmd+Imz4/EPSWLAbudjcF66U60W0yDV8eqeA\n7msMc0Jb1MWklEDCdvpNKxr3RCWa/mLyVpm0zInWX+II/Dk/pQdh6bCkH1zW\nKsAOb6QnbWZsDQgd9MkO4Gb24DmFaMX9gWlucO73/HN1YmvNhA/bt7DEDxXJ\nlzk9sKYM2U7BmT1rhcpWHzuPA4hx4YMA8Nv5HSXvzXZUsV1ouRm9cFBuB7KR\ncoBBhAybtISOY14tzT51qqXUtIIF6vSdYN2sfncxHAWdPfNsFfr00KYnZbc5\nE4irX8+Uqc2r/ybbffv7xDTALpI9j8DrR46uTGaiPxWL4wYVuEYSUqns8zeK\nqRdgsaPP44nlXuW8XO0vMjgBTcydYedqoETyGaUi4HLbTGE/g8wxNtWA2VZ5\nGEEj\r\n=Ftcg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCMjrB6iN/etO5X6sxjxw3haSdzPmuMdp8J0jeLWG8rnwIhAKal7ivWjIPGfjNDMG29gbdsmbQRm1EUJM2YhL5d5/gY"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.1510_1574176256309_0.17132796067485434"},"_hasShrinkwrap":false},"3.0.2946377":{"name":"@metrichor/epi2me-api","version":"3.0.2946377","license":"MPL-2.0","repository":{"type":"git","url":"https://git.oxfordnanolabs.local/metrichor/api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.1","@types/axios":"^0.14.0","apollo-cache-inmemory":"^1.6.3","apollo-client":"^2.6.4","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.574.0","axios":"^0.19.0","core-js":"^3.2.1","fs-extra":"^8.1.0","graphql":"^14.5.8","graphql-tag":"^2.10.1","lodash":"4.17.15","proxy-agent":"^3.1.1","save":"^2.4.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.6.2","@babel/core":"^7.6.2","@babel/plugin-proposal-object-rest-spread":"^7.6.2","@babel/preset-env":"^7.6.2","@babel/register":"^7.6.2","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"6.6.0","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-import":"^2.18.2","eslint-plugin-prettier":"^3.1.1","husky":"^3.0.8","lint-staged":"^9.4.2","mocha":"6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.27.2","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.12.1","rollup-plugin-terser":"^5.1.2","sinon":"7.5.0","tmp":"0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"npx mocha --recursive --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"d1b6be001531a17e510abce061250e16efb23a9c","_id":"@metrichor/epi2me-api@3.0.2946377","_npmVersion":"6.4.1","_nodeVersion":"8.16.2","_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"dist":{"integrity":"sha512-bJY0+QouAofKI8TLaFgLixj6DfgbQ2sMiS4ukpkzf07JjKDrPAjr0hNA2dnUjRmuL5Mpt3DDCBWhFopyFsuEmQ==","shasum":"d405b69e5648c4a5fd5659c848eb2f7d0b3c6bbf","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.2946377.tgz","fileCount":118,"unpackedSize":554546,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd1AqoCRA9TVsSAnZWagAAMUYP/jphO47kVjk6jM40A70s\n6p8ADQRYEC755HOe83gXkb9FC6cg45EuLwVDdbhI7WsULg2sJbZB8mshnryl\nSnuHdUTfMqEzXHeti8FqGxqf8j+EemwdoAOSKttmICvxVVDbkcAJTa0aQRG8\nJlx1ocwty33ms4sQ+1TzSQeqIQh+E7lc/fy92/MjCDISDvqgigpFcNmWiPr1\nYftcQ2ATBryvSbgPGdj9Tvh8TopAFUVqfVAPI8byjzDtCa4dJXuILNLEAV49\nymLChkAcY7B64gdJXQDXGypwYcNPaOy8Ksm5GRRY19KMaT8HZhHaWE8Osx+T\nfkzaLxWGfpC3aMPUDob8SPISvAswSlUjOh9/g5MD6q4mitrRH+/0tp+aOwkB\n2yq1alJdqdoykVwzJG9jDU6xWOFauzWWv6QLDu0ska6KRGGa2ov0CKhkqaeE\n8lwQqm4dT5kJKB1kV59+s29I2LNH85Ue+bvBQyHnkuOTMZ0vG1fLaN1MsFko\nOzSG0qx3kLYsoYgYwr8RqfrVLIx1iJitRlZz7FOw9odKaq7iDT1a03Gub2rU\nLFrDlPThPOjq2xtRMh/OjLQ+j42gzpVjeJQNW4p8oUrwjL2Cv0qq1W2tAMPS\nHlkNOFoz8mPA+Ag9qT/FpOpo+sBoFW697d4BfMOZwDlYAiZzT+kC2mSgIudz\nsCps\r\n=eLYW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDMU3ngw55TGkuEOUUIoOjw99KMocKwkJYe8OFzPDUcJwIgbxiado3x76H/RNPk22Pmc6Eo2oenZPb3/cpeN2ylhhg="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.2946377_1574177448516_0.7856955783170378"},"_hasShrinkwrap":false},"3.0.2996439":{"name":"@metrichor/epi2me-api","version":"3.0.2996439","license":"MPL-2.0","repository":{"type":"git","url":"https://git.oxfordnanolabs.local/metrichor/api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.1","@types/axios":"^0.14.0","apollo-cache-inmemory":"^1.6.3","apollo-client":"^2.6.4","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.574.0","axios":"^0.19.0","core-js":"^3.2.1","fs-extra":"^8.1.0","graphql":"^14.5.8","graphql-tag":"^2.10.1","lodash":"4.17.15","proxy-agent":"^3.1.1","save":"^2.4.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.6.2","@babel/core":"^7.6.2","@babel/plugin-proposal-object-rest-spread":"^7.6.2","@babel/preset-env":"^7.6.2","@babel/register":"^7.6.2","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"6.6.0","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-import":"^2.18.2","eslint-plugin-prettier":"^3.1.1","husky":"^3.0.8","lint-staged":"^9.4.2","mocha":"6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.27.2","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.12.1","rollup-plugin-terser":"^5.1.2","sinon":"7.5.0","tmp":"0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"npx mocha --recursive --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"db5bd17fc702362d9d8b8be25c44cb95c5f53bff","_id":"@metrichor/epi2me-api@3.0.2996439","_npmVersion":"6.4.1","_nodeVersion":"8.16.2","_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"dist":{"integrity":"sha512-GtNrDUfKWo2R8/r8BxlT2YcPXadUwdsjAn0eXxnj8WmOUnmPtzoXFPJSYLcyXSir9Fh/1f0Zf5ve73CWKj2DKw==","shasum":"80da9b9b97dd273a8d702cda0f947bf32187a9c6","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.2996439.tgz","fileCount":122,"unpackedSize":561925,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd5nsMCRA9TVsSAnZWagAAM7AP/AnE6T+kW5VkLwC2zhJl\nlhnmMt5/J80EtOjAqNGfFXHKJXJkB7KMS3UXXyB91WHUklB9ac1ZKfMWUITq\nDKl5rRKF0h5j71K3Mmq0KO6LglNNQaIt3eB3qfQjpqM87sUwHRCHgV24N73v\nQSrWkNbce/W5YwjjPDeV+lcyUjn0sO/2Wuzc1BAnzuLwVyFEc11c4+KvYHDh\n14KXUOYG1B+81m8A3X7CiVSAbGovZVctKSahPlhaljuccm/h9htgOL6Wu/xU\nWeFnB12vSngaq3+45B+gKEV21T9LLZ2bkeSd1BjXr7NL1NHpO3jSJlERXR4x\nV4uSLXn8Pme/0kYvfFSq10HjrohqiRsSIcmfkTQ/1OW7R6AEYWjLyHvWWwCO\namP+d6FGVq4KC1ssYL7l8/ALIDIvJU++11THnDr1DDLWg3Jx31+djlU6GPMN\nH4LF8R/MS0r7xrhf6cr51bG0qPCuh/DzH7gu6nz8G14qLsnjMiNSyM57pVrm\nGcQlsdBLUo+eLrVJ0Qd5/TUUpx6rSl8DawakJ5QcKn+Ppc9i3g/nLzXHyy2m\nXaGx3iKahtPftXz8JAXp9QAGULXPe5MZFDrBZSiBXw8adqy+AiPBm9WgqbYM\nDUUst9Mef743D92RGoEOg4G0lgnGObVdx4Q1hf3SvlDOzC33yK11+nGvlkhD\nK15J\r\n=owY3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAQwCskBK7eQBTtp/oy91k0tHap4F4CWxjc7hprqH35JAiAEaf9M5QXZV60CzT4ydKbiwxJO1CgmQYSfVjoM7Dt6zg=="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.2996439_1575385868135_0.41799702173553444"},"_hasShrinkwrap":false},"3.0.3010186":{"name":"@metrichor/epi2me-api","version":"3.0.3010186","license":"MPL-2.0","repository":{"type":"git","url":"https://git.oxfordnanolabs.local/metrichor/api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.1","@types/axios":"^0.14.0","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.3","apollo-client":"^2.6.4","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.574.0","axios":"^0.19.0","core-js":"^3.2.1","fs-extra":"^8.1.0","graphql":"^14.5.8","graphql-tag":"^2.10.1","lodash":"4.17.15","proxy-agent":"^3.1.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.6.2","@babel/core":"^7.6.2","@babel/plugin-proposal-object-rest-spread":"^7.6.2","@babel/preset-env":"^7.6.2","@babel/register":"^7.6.2","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"6.6.0","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-import":"^2.18.2","eslint-plugin-prettier":"^3.1.1","husky":"^3.0.8","lint-staged":"^9.4.2","mocha":"6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.27.2","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.12.1","rollup-plugin-terser":"^5.1.2","sinon":"7.5.0","tmp":"0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"npx mocha --recursive --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"71f613b34ddd726bd27041393ff6e5934754f756","_id":"@metrichor/epi2me-api@3.0.3010186","_nodeVersion":"12.13.1","_npmVersion":"6.12.1","dist":{"integrity":"sha512-XBnG3isPMs9vMzJ503v/wBmOcUCPeuHDPsh0BWmjgWDLa8epVztYJHt+5YLBkoG8wHkvnYMmAjPcivBVaI7jxQ==","shasum":"e8a1a3bdac95ff12dc6e0b5e309f8604347de9a9","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3010186.tgz","fileCount":124,"unpackedSize":567650,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd6o19CRA9TVsSAnZWagAAgCgQAI7KbRNAkxgAWlAsnNoM\nEFxmoofafZ0MF5MJtEjo+cxWp990nUaNCLOFZVtYbB/5UnlkKAmC4Y5kMBYs\ncuSn5cgG//duKY3IqeYIB0pqs2dvBACqNC+iZA3+v4Sh1om2dMyZsZ8TWsAm\nnw4Putx8ORJyKmsLq6LIqztwP8hh8x4+ZenLjgo67zh4DQM2H+MLtFf3uzj4\nGnbc9Ap13flOz8i0oW4XqZH0nNJhw/zmEZnk+WtR4NWLYG6wMSWOasXXoDSy\n/WGAllwAKNUxodpyn82V/PjJQStipB4TmrNpg06YxCpu57sIxb2oviEmHjFl\nM1RAF+KVPqv2y0JanUm5G5fkKHFgo9vb6+HFQ6+PlGOVQ2TTCVIu5LdTxrm1\nF2HxFXtla93XZLqBoCC0LzMERBZSQ8AWj0gAej2eeMoHHykforGgIKkwCKqC\n6Yt8JGA+C+GFXHIWVaavcLMrQp7WzUvoXZ+h4d16j0huwxACrXX7KvsIYXab\nS/IoXQwah/I8IvMf4mB9u+sCKHRN/ptZwk6/JFFqglJbUAKS7QpAoz3oQqlQ\n2GOlrr3BmL/DUGWHosfQeDOwH6cNGRjCPo/+zAS9w1gk7iAdNTwptE4XULX+\nD7oqfr4+qVq4cBk0Zh1FX1t7yNJEQwsnwlRDT7W51K2CrM/lJntWXqcekbd3\nUNMd\r\n=9nHe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHgl71qIl9rSS34hTg0umrxr3ELxNsZN3wNqQ+YNLxQVAiBgaZy+0VAISXKv/iJqepPAD9O0VAwaa+Z3nhRHNdPpLA=="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3010186_1575652732656_0.4281804625848127"},"_hasShrinkwrap":false},"3.0.3014799":{"name":"@metrichor/epi2me-api","version":"3.0.3014799","license":"MPL-2.0","repository":{"type":"git","url":"https://git.oxfordnanolabs.local/metrichor/api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.1","@types/axios":"^0.14.0","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.3","apollo-client":"^2.6.4","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.585.0","axios":"^0.19.0","core-js":"^3.4.8","fs-extra":"^8.1.0","graphql":"^14.5.8","graphql-tag":"^2.10.1","lodash":"4.17.15","proxy-agent":"^3.1.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.7.5","@babel/core":"^7.7.5","@babel/plugin-proposal-object-rest-spread":"^7.7.4","@babel/preset-env":"^7.7.6","@babel/register":"^7.7.4","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"^6.7.2","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-import":"^2.19.1","eslint-plugin-prettier":"^3.1.1","husky":"^3.0.8","lint-staged":"^9.5.0","mocha":"6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.27.9","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.13.0","rollup-plugin-terser":"^5.1.2","sinon":"7.5.0","tmp":"0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"npx mocha --recursive --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"79aaa404a511a801733c7f46fdd997733dbe3d23","_id":"@metrichor/epi2me-api@3.0.3014799","_nodeVersion":"12.13.1","_npmVersion":"6.12.1","dist":{"integrity":"sha512-IR9DsXJ3ixjHIIdA20rDinRny8o0dLEp6VUrvo0tL4bRwdZ7T0CyEV1SALEOIyInc5+3I4hIfKLxXO+k/2yUhw==","shasum":"097e8adb0d77d1bedf6330527cdf655566d96e9b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3014799.tgz","fileCount":124,"unpackedSize":570817,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd7oCICRA9TVsSAnZWagAADSwQAKE56GkrnZIiuw2N5ZcR\n58DjCfFl0MYa2UWVsEd8ui6yxsvcvJDXZLCp5zNT7iYOsvkH8tIPEYQ6IsMv\nGY3nTPhZFFCOL0HrXGoOQl9xxAnlB0dIVnydd6k0mOL/iGm81i6kUWgo/P0T\nzX7RMVJBEC1h22a1vsAtV8tTwyeop42hAFPGL4wLFBOH5vPsY4bWvgG78TuQ\naK2GKPzJTINOoVe20+OCPBpXpMMd9BM8lq2MD1inxQ+OX7IjKr8epTyxdij5\nQQljWWb9P+GVV6uXif/EqB1m6dONHgi1+EcK+7ThCj8LC8Wc7qBihf9laX2g\nNzI3TFsbMiYwQmq0GB41K0Up9e1hf9C4YUG33YQQ2bkC84wAqIkTzDGyARIP\nIhkNaixyCmQEHs6qN9fKdjnNv2Ymotxf36z7wXsdcsBB9ZZyIQNRKP4v/tSp\n3CNFPYGZj+KKyZEUy5IJRfL25RNt3IF1Fdkw7lM0WqqVrHYVkQYjS9P76W+d\n71JQuwowD3QU7VzggUIyIfT2BtrDbeS994ZsuVBPhy0yF+RUu8bdViUNCHiq\nfdscBNj8bsr0SC5tafGFKABkwaGgQBwTEXS1IMQNrWDNIAT1/UhcNDzqMy4q\nBulpTrR+YSaPfWvXf9hIxvyUNmp7MLxk5083sjLopmJQDKqNFFcIJsDqUgM4\noBSS\r\n=sPQ3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDEH/P18n3+Togsm3jyMlz4Xc3In0c7sPDnt099C69qRgIhAP3jsoIkdz2tcFiV+IUDXkiERNF60qHvXNuPYBOLJ6Ji"}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3014799_1575911560145_0.3235297968422022"},"_hasShrinkwrap":false},"3.0.3020472":{"name":"@metrichor/epi2me-api","version":"3.0.3020472","license":"MPL-2.0","repository":{"type":"git","url":"https://git.oxfordnanolabs.local/metrichor/api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.1","@types/axios":"^0.14.0","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.3","apollo-client":"^2.6.4","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.585.0","axios":"^0.19.0","core-js":"^3.4.8","fs-extra":"^8.1.0","graphql":"^14.5.8","graphql-tag":"^2.10.1","lodash":"4.17.15","proxy-agent":"^3.1.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.7.5","@babel/core":"^7.7.5","@babel/plugin-proposal-object-rest-spread":"^7.7.4","@babel/preset-env":"^7.7.6","@babel/register":"^7.7.4","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"^6.7.2","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-import":"^2.19.1","eslint-plugin-prettier":"^3.1.1","husky":"^3.0.8","lint-staged":"^9.5.0","mocha":"6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.27.9","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.13.0","rollup-plugin-terser":"^5.1.2","sinon":"7.5.0","tmp":"0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"npx mocha --recursive --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"2ab721040bcb259edf5d87cdb5e6e40a36f89c7d","_id":"@metrichor/epi2me-api@3.0.3020472","_nodeVersion":"12.13.1","_npmVersion":"6.12.1","dist":{"integrity":"sha512-4tkt9Qp+dai1LbssabyGzMLZpTlo0zPqRhuYWcjto1noxQ5esYNOAaU6R5ZpETv1x0CnGht5tSn0iLKMxn5Txg==","shasum":"8261fb0796decaace558baecc2c5fa2150e492e0","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3020472.tgz","fileCount":124,"unpackedSize":573897,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd79OdCRA9TVsSAnZWagAAwvkP/1AniyO95TiG+wJYJPk7\nRMTqTnqce+ZrHeYvteXzTHrWQLmc1lGXP3ZRT/B4CNaIejsswo+SObVrAFJv\n9KTo2aBgmMm9rT8T0Ua251WK8Vxs2ZLXWAAxoDoqowiLMZUejabsz3/q7+i2\nz8frchFxipYI7vo6+Pbfc2Vg3S3RGlve4DLg+/XCTNL8hXjdIQt7sdllid50\nnynqH/ud8dYbdt8C8Z+XKaFQJqzYjDCWOHZj1OC4uYiXCmKwq1GeOld7poGr\nNR+h7FvWr0qW8ibfJ+n9rl7b0iVaLrl3qkxxdKXusvCY31jhLXiKP563ewC7\nbnSX7C0ogeW+qliDb9M8bU01hKvl02UX9OJfnkYQAwZ8xsXQOEO1O13FJn7o\nuQTJ07nKBWU3s/vhtnUBQR6yThRK5TzB2e4N6DmwP8XQvuMuIaFjD/2ZyTNQ\nEabk4moT5GQZiAO1GRcboG9KHjDgxZ8a4IbGLA2ZvFk8bkdc+cuZuUT69+aW\nvkDnrjgA1iJQ5yRuiKiI604KA15+aK3fuHe0wQmbzz86JZRDbQMSsB5KXcyn\n4oLYRcc3+o9zT2pfMunFKsuHfw/HrbkrN9ScPqag1nOs38P9UXiNk3cqFY9t\nhH0h7yAwuZWGCWyv9Cjw+sfsIT6QLQXtQNGnPqLK8uEdBARtCB5L8mTNL1cV\n4zp+\r\n=tYNf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDZFslBQttJyB6AzSg31J7xGNou+nwZj3q7aeyJQAAXuAiBvrVagqY7uenQbP0fgTIDc5gHbl3NNPr4BhrJcQ0BrGA=="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3020472_1575998365202_0.8891723789142152"},"_hasShrinkwrap":false},"3.0.3025991":{"name":"@metrichor/epi2me-api","version":"3.0.3025991","license":"MPL-2.0","repository":{"type":"git","url":"https://git.oxfordnanolabs.local/metrichor/api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.1","@types/axios":"^0.14.0","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.3","apollo-client":"^2.6.4","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.585.0","axios":"^0.19.0","core-js":"^3.4.8","fs-extra":"^8.1.0","graphql":"^14.5.8","graphql-tag":"^2.10.1","lodash":"4.17.15","proxy-agent":"^3.1.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.7.5","@babel/core":"^7.7.5","@babel/plugin-proposal-object-rest-spread":"^7.7.4","@babel/preset-env":"^7.7.6","@babel/register":"^7.7.4","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"^6.7.2","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-import":"^2.19.1","eslint-plugin-prettier":"^3.1.1","husky":"^3.0.8","lint-staged":"^9.5.0","mocha":"6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.27.9","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.13.0","rollup-plugin-terser":"^5.1.2","sinon":"7.5.0","tmp":"0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"npx mocha --recursive --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"4dc901002a686aefa338902a85c417c7e84810ee","_id":"@metrichor/epi2me-api@3.0.3025991","_nodeVersion":"12.13.1","_npmVersion":"6.12.1","dist":{"integrity":"sha512-cCpWe1JBDhRVcLT3Q8UF0HjN7SHlD845qKe9vzJmlAzAHYPqeQVdlF2e1M9so+3CNIXwJtwtt9E6xFxii6e1cg==","shasum":"e831d64669c948da48dfc2c1fdc1f1bfb6929d89","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3025991.tgz","fileCount":124,"unpackedSize":575468,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd8UcYCRA9TVsSAnZWagAAcsoQAJuLTbtqB4f2KYX0Ibhx\nww6L5koIYHSsfvs5iQCmRQDLACfmV7IveJzaDd78ostq2NX/jRKXmVP5W66Y\nJFCY90/Mpeg3ID95QS8gDxM5IA1lrHPtqlbLizBedbFeYzRL4EBc/AOBH+GH\nRsAyz9C9QeFh/4v3FroZCDF7RY3yuwo6k3dUpqiqrstJ0/KVFiXQHBTw/hVe\nIp78BztzLr9dcZCKhs/Ek8PgDk/lI2y5rTk2Btx4TGnRWLhFTaR9lceZzE/I\nTHfHwWS3PjybwMhKdTu8OhjGcRBFMzGuzRpxYJsOBVu1f+4pnu9r8plpUFCS\npw1pGtQur7hQ22lwUmFHhCP7L9dfZRTmcGojySIbrUIcpAD+5Lynu5M3v9pM\nCWJQjakf5J/C9nM/Skw7//SsjV+j9N3ponmvqKeGNRs/YQKs00upL4W1+ewm\nFhIG9xlBkQuxO3Y3CbF2XUxvcCHIzie2saj23NL6PZY4gHA7d0EER3ZQKlOW\n7tLbe2pSZ9dSNlZRWQME/E8YlpsVTgXt1x+G/7Do3CFETwKmXnGZVmitqdbI\neLEEcUFU+CffXm6DWAvAqt82QLgSw2IXx1eASgDTu2AV7XvYNkwS4KxU6Rcg\nW2wk1SACTD2RAp/xu+N515ndj6dNtew//qqsax7lRmAEsEO+S3ntKbKwacIr\n2bre\r\n=/Abx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICQKn4rQ2SEOzB1erneV+9fGtvnzjkIAxkm7MxxqLgmwAiEAkIPtXPlwrVf7em2uQ0Ie5H9lK0PbwSM7+6oeBzoG2cs="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3025991_1576093464437_0.10329354613774289"},"_hasShrinkwrap":false},"3.0.3090503":{"name":"@metrichor/epi2me-api","version":"3.0.3090503","license":"MPL-2.0","repository":{"type":"git","url":"https://git.oxfordnanolabs.local/metrichor/api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.1","@types/axios":"^0.14.0","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.3","apollo-client":"^2.6.4","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.585.0","axios":"^0.19.0","core-js":"^3.4.8","fs-extra":"^8.1.0","graphql":"^14.5.8","graphql-tag":"^2.10.1","lodash":"4.17.15","proxy-agent":"^3.1.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.7.5","@babel/core":"^7.7.5","@babel/plugin-proposal-object-rest-spread":"^7.7.4","@babel/preset-env":"^7.7.6","@babel/register":"^7.7.4","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"^6.7.2","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-import":"^2.19.1","eslint-plugin-prettier":"^3.1.1","husky":"^3.0.8","lint-staged":"^9.5.0","mocha":"6.2.2","nyc":"^14.1.1","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.27.9","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.13.0","rollup-plugin-terser":"^5.1.2","sinon":"7.5.0","tmp":"0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"npx mocha --recursive --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"fd4dfbd7e2e7b8b51c854f11de70353a6ca3a5fd","_id":"@metrichor/epi2me-api@3.0.3090503","_nodeVersion":"12.14.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-8lf0OgO0fOoPhGbAe0mh/DfFlFIGDhFR5ygkpYCL8zT3R01J70OoCRAtiYgNPtyS+2VkD0nlbT+FH54ZWGX9cA==","shasum":"10c971dea3dd7a88d1be62b4bca84731a3b43426","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3090503.tgz","fileCount":126,"unpackedSize":578796,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeFy7ECRA9TVsSAnZWagAAt9QP/0j2WW1MvyAprVWKVnK+\n1aNQIbARHo7FX+FAY3bGKPs8wstiRNvPFEIk+cUraBINK5/qRdPuwAOqFCXX\nSuVUQbrmUYcufXBY1J7LgBAV2aQgQfbtH3mflghwmSpfAdUqR8cK6EuKkaLa\nd3bxd666YYVyb9BNwXXjprk+QkcDGG79JlqUcpRk2+6oIcR2VrUtx1ECYAVb\nQt1TjHpvkbRq9cNRTn3+rkW5Q6a4luwe9nIMo9FnasjAQ9IjFtnnXlaeucg8\nNQ/tGFxD4AHmbB+FGYooa94PQBGEcMZG/5tQw5R+dJbiiLT+EPCvj9K0U+F2\nNv0ysNbddV9BsYbXxfpyJEEweWIdNKgJNMtjathKxCeI6wurKXKiehTBEzNt\n+Huj+HoT0jQ0LPFK6f5JY0swvp009m4EI1wtBgddBftWRb6EAoYymUox/Yac\nDATw+dQ6+SLiUCu/Hlhkk0yb0iA95rrxhhq3dRv5aZNxhmRcuszoqbg4rl0T\njuT6x6lPNKWtmDiKjTrhtQzooS4ytKTpSzZ8Txk6I2f4FbDsoTPPzbAU/661\nl/ALnThBSpq1fNvoRogiHvJRIhk9YsCdac60+BKfCrV6kqkjPX60Ie63UEMs\n5zamaWyZi1cKq33822gl+0+uy0cHeTubJnVR12I3uglN3uy8LJRfkRZtp/bT\nxEGj\r\n=5mS/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDHdirTiBX4sBfIuOoQiHqaKti14OJUTr9qlEPzDfMorAiAy8jgma4OH/9LSrRq5U3twM4ZY78Dui7BK3vk5PqLN5g=="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3090503_1578577603886_0.15178804218520558"},"_hasShrinkwrap":false},"3.0.3182029":{"name":"@metrichor/epi2me-api","version":"3.0.3182029","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.2","@types/axios":"^0.14.0","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.5","apollo-client":"^2.6.8","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.10.1","lodash":"^4.17.15","proxy-agent":"^3.1.1","recursive-readdir-async":"^1.1.6","rxjs":"^6.5.4","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.8.3","@babel/core":"^7.8.3","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.8.3","@babel/preset-env":"^7.8.3","@babel/register":"^7.8.3","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"^6.8.0","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.10.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-graphql":"^3.1.1","eslint-plugin-import":"^2.20.0","eslint-plugin-prettier":"^3.1.2","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^7.0.1","mock-fs":"^4.10.4","nyc":"^15.0.0","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.30.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-babel":"^4.3.3","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.13.0","rollup-plugin-terser":"^5.2.0","sinon":"^8.1.1","tmp":"^0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","lint:errors":"eslint --quiet --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require @babel/register test","test:single":"mocha --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"c9277cf08f2643addcc8e42dca4fd9a78b0e5607","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@3.0.3182029","_nodeVersion":"12.15.0","_npmVersion":"6.13.4","dist":{"integrity":"sha512-XLTQYtE+vEiJW6OJt+vVkhve+C3M2cKHHChhh0Iv7O6LX8NC9zLmcHB/vsAAc4tSXg1hlIgU0sFhmiD9xSF5bw==","shasum":"0d30fa4501ac36b05ee1448d3927bac7bfe78791","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3182029.tgz","fileCount":135,"unpackedSize":588286,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJePDpWCRA9TVsSAnZWagAAIiUQAI6wmtLkmxfxY7kj0o6D\neu/Rbei+/qjNH/iBzdNbG2O0DIwEXPmLQaVuLDkvmp/5xep8Gew8+wl0u8+u\nEXdmhPEfevVZ5iDHFi81v5LVSWT7CSOoG4ZBADUGeX74m5gJYOCRr/QZwOMm\nsk3UV5CRq4jIrnY8Qj0pFvlPCsuiLG/mCfEEbS4TZqt+sq7ubly8ukccDT3k\nN2Iu1tyc64s9fw3OHAsZTWq8+7q7fQksLwjH0pYUh5XWUGlv6u1oKhGSXJMS\n28BP205QtYSbp3gQzRM4aTRciPfc6VEqKqpwTZP1R4mNEZMO+y4hIciZrH8c\nyBQZaCOZ0ga/I97gn0x56Yyv9y1q7q1YSwxHNirW71oTPW4jrw34c/ii+Vwp\nh+BS3EFT9TEKJzcRYP6Pvx3WzDAUcTS0azyhgliY+0NnRLzEe71bXiatZnDV\nH3GZFps5GKMqz695ULwMCnioPPYM7qb77lm/75XKnnWGuTyOoPm1TcUHZBZ9\ngiGKpBGE7ohWaI3PI0h7pKbtd7iUOAEZTy1gbrJr/ezuWx8YNe58R37l3n0e\nmW2LPXtXGkWSKtYsLVKGyo/Wl6WenRshkLgvxLJWz/eHXKDIoUYg76RynbUe\nEaiOYmj+DGmVJENQmKs1CEh+lHpZNxTNnd1y1wwGmYb8GjOlE7fzDVryQbk5\nDupq\r\n=VOcO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVE9w34DAfqD1VWA5HZ0z0Q0la/cvHRL3+du1UuT4BLQIhALAToqwAADEDlkqUddatJAlXmEkYa3OTR20dWBdlqShw"}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3182029_1581005397462_0.7451958359771296"},"_hasShrinkwrap":false},"3.0.3187188":{"name":"@metrichor/epi2me-api","version":"3.0.3187188","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.2","@types/axios":"^0.14.0","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.5","apollo-client":"^2.6.8","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.10.1","lodash":"^4.17.15","proxy-agent":"^3.1.1","recursive-readdir-async":"^1.1.6","rxjs":"^6.5.4","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@babel/cli":"^7.8.3","@babel/core":"^7.8.3","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-object-rest-spread":"^7.8.3","@babel/preset-env":"^7.8.3","@babel/register":"^7.8.3","@types/bunyan":"^1.8.6","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","babel-eslint":"^10.0.3","bunyan":"^1.8.12","eslint":"^6.8.0","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.10.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-graphql":"^3.1.1","eslint-plugin-import":"^2.20.0","eslint-plugin-prettier":"^3.1.2","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^7.0.1","mock-fs":"^4.10.4","nyc":"^15.0.0","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.30.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-babel":"^4.3.3","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.13.0","rollup-plugin-terser":"^5.2.0","sinon":"^8.1.1","tmp":"^0.1.0","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","lint:errors":"eslint --quiet --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require @babel/register test","test:single":"mocha --require @babel/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require @babel/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"4c04ab7dd2ea2708bf87d41d44c9026307a09308","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@3.0.3187188","_nodeVersion":"12.15.0","_npmVersion":"6.13.4","dist":{"integrity":"sha512-Fo1f2XiE+ktRZi7mmPpHxdFrcsyYDdE1q+jZ7MtfFO1D1cIQn+J/VodZ8DpMfJnGwzs78vKabVpLUrlfPyx51w==","shasum":"7ff9303b27c112af89ca63a49a6aa4d2eb0b7d4d","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3187188.tgz","fileCount":135,"unpackedSize":589064,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJePZqmCRA9TVsSAnZWagAAasoP/A4xnYRfidITDtHwZZID\n7ewF8ByvZow+wzO/3+KOI7fr56v3kokH/95gpzeuyUhWZZMivVjYS9DzILIB\nAKY6GsqvTwO95wGQ4ZnV2oneALw3/VhE/UyioSw41uJ4g5QqzUbEmAY1PJtv\n6jyVIP2bEnlEPEVDTBZaKk0emHNmX7cMKzkZdxny7qw4NU8jLAAFa/vK8ea3\nvQ9E+XmCHgJYkKa2rWUMfx/9oP0t1MOB5KgAa9qRo/hFpw1AtMnXB7ddSoUx\n92LiU/VtEhZB8CenQf4Pu+b8fRbb1sAdAXwyRqF86mEtfOyfL6jqif+VJoUP\nBvqhQZ/vv4XcKwWtRciLf757SSNei0M8TWXMnRXRvLz3eU7uqQlffy/4lfae\n3iQShjp2YfYQX6dZzmTYSSCgtaQbpJsj4c2OjR8PGhC4dThgR5hfuQWwUKkx\neqfOn5YQPnQDm7Fb8NxsOvOxuhb7ROq+onOZVOSZRXpp//dkTw3a23f+2m98\nwzIrdNezr/8tGeAHsulLty4WKDQlhZLDExJ77HEaZPWRZZFpAj8Yzvur/+oe\nx1TCH4kHmnCzFeCqaAXNSvmXOjgzblxan1dFXiupQF7fSOWubq5aQtFVvSc3\n86kGqMWFHZD1bRYZrRLJhXJRGEm5klWF+8U6QfEbrHlm1LzV46mjlSW11MOV\nWTGi\r\n=t/xT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGc4cEVHQvBDkhSi1h42o1mgLsFb7U2ffrpyfa0Odk13AiEA4RcSUavQ4XHoSBijRt+3mbBwSpAt9PBZpw/9CzKJwlw="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3187188_1581095589547_0.5765190220285967"},"_hasShrinkwrap":false},"3.0.3339019":{"name":"@metrichor/epi2me-api","version":"3.0.3339019","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.2","@types/axios":"^0.14.0","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.5","apollo-client":"^2.6.8","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.10.1","lodash":"^4.17.15","proxy-agent":"^3.1.1","recursive-readdir-async":"^1.1.6","rxjs":"^6.5.4","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-sucrase":"^3.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^13.9.0","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@typescript-eslint/eslint-plugin":"^2.23.0","@typescript-eslint/parser":"^2.23.0","bunyan":"^1.8.12","eslint":"^6.8.0","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.10.0","eslint-plugin-graphql":"^3.1.1","eslint-plugin-import":"^2.20.0","eslint-plugin-prettier":"^3.1.2","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^7.0.1","mock-fs":"^4.10.4","nyc":"^15.0.0","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.30.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.13.0","rollup-plugin-terser":"^5.2.0","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","typescript":"^3.8.3","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","lint:errors":"eslint --quiet --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"TS_NODE_TRANSPILE_ONLY=true mocha --recursive --require ts-node/register test","test:single":"TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build"},"gitHead":"d022e08a275198e57edc16d5974128615ed41692","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@3.0.3339019","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-xFIk9DSGCttdPafQgh+Yrpyo5P9zXFPnOfZQsY5J6g3sBaLAnJvBIzDZT59aAz82NN50is1WKfAu3TabJeNnPg==","shasum":"0fb4951f4ad9aef7f1015a0cec9f82d180616e03","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3339019.tgz","fileCount":138,"unpackedSize":604107,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeb51kCRA9TVsSAnZWagAANRkQAI2mSg/ZkxSQJBSCTZ/r\n0r5Yw2TCzxY6/EZcOdUfvGr2vqU8jlE9/BVUyPvxMSj4zd1A6pzOr9u5I4W3\nXhbQal2gye0CgOJfF5ODLwDtegutWLclNOAtRHYwz/7+pg5qqEXAPv8gOGO6\nfX8QBe3MeduB2ZAfsX134oLfwbfDBsMl2yZJleOhmNZn+w+9AT0xp2o9T5Ge\nQPoAdzeQlqpiyXZAbq9ZPs8RZUfuC5oYElyZghaxSg5hUyB3WuKs92mwpFA+\ndeDGU8l+biOollf5M6oWkUtq5OIMIEXBOKfFQyoACmNjpvhKfPXQ0TrAtUOO\n1UyK2yPucjTg90ydm0rk+IxpXt+YT4tVXYRSdArzuoHr0+I/AyXdFqnkG25y\nL353Av8JFMgW50xq4jl+x+hSLv7nYt/J6uIC3+Be6cqjw7KX6wfI19J9WdqI\nrzbXoroJQm2hezDioNGDucvSGeXljD10SizjsZkNJe0axmTlyYmupAiFohzm\n7P50GG5ledqvKWjBA4D2jsCpQZ+f8hvzonnXaPPz2ge5sDZrJk1L3qHMBXQ/\ni2CylaP2pSNAp6hcu+dF6O7sMDnLRLmlHjgnYeTnkzIrhtY9/H9Xq8nbU79e\nF5pyNa0qvDgp6iw944J/gqW+Rfut0TkfaezKRul6XEhRajNvfjUCbUZmgKX9\nzDnu\r\n=qFC8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDJo+eAaWaoeVvNvYHnSpLs38Pn+3AtSmdQeuJ1+iA+SwIgKSXgLSU3wt2K9t+pRD0ScW1W9esruAELIh5bbpHplFQ="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3339019_1584373092045_0.42102079253564684"},"_hasShrinkwrap":false},"3.0.3683829":{"name":"@metrichor/epi2me-api","version":"3.0.3683829","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","main":"dist/index.js","types":"./src/types/index.d.ts","module":"dist/index.es.js","dependencies":{"@lifeomic/axios-fetch":"^1.4.2","@types/socket.io-client":"^1.4.32","apollo-cache-inmemory":"^1.6.5","apollo-client":"^2.6.8","apollo-link":"^1.2.13","apollo-link-context":"^1.0.19","apollo-link-http":"^1.5.16","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","fdir":"^3.2.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.10.1","lodash":"^4.17.15","proxy-agent":"^3.1.1","rxjs":"^6.5.4","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-sucrase":"^3.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^13.9.0","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@typescript-eslint/eslint-plugin":"^2.23.0","@typescript-eslint/parser":"^2.23.0","bunyan":"^1.8.12","eslint":"^6.8.0","eslint-config-airbnb-base":"^14.0.0","eslint-config-defaults":"9.0.0","eslint-config-prettier":"^6.10.0","eslint-plugin-graphql":"^3.1.1","eslint-plugin-import":"^2.20.0","eslint-plugin-prettier":"^3.1.2","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^7.0.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^1.18.2","prettier-eslint":"^9.0.0","rollup":"^1.30.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^0.13.0","rollup-plugin-terser":"^5.2.0","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","typescript":"^3.8.3","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run fix-ts --fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint-js":"eslint --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","lint:errors":"eslint --quiet --ignore-path .eslintignore --ignore-pattern \"!**/.*\" .","fix-js":"npm run lint-js --fix","lint":"npm run lint-js","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"TS_NODE_TRANSPILE_ONLY=true mocha --recursive --require ts-node/register test","test:single":"TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register test","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --declaration --outDir ./types --emitDeclarationOnly"},"gitHead":"2ddadc79383101cbf7218a03e9d28812ba011030","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@3.0.3683829","_nodeVersion":"12.18.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-oJOQFPazj1V4QQww/uaT912M5u/08sWeZfugQ2slfqeB5T2LqEE0/GrYdK2d7Vn8k4kLZySXIWtDGEAARdjgnQ==","shasum":"f13b1e70451572cc2a75ce9f82e1c4a7edca3c8a","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-3.0.3683829.tgz","fileCount":173,"unpackedSize":649288,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe18P3CRA9TVsSAnZWagAAEoUP/02GOpKQPm0EIYjMI/sP\n2YWTzdSqIaIspDt9diBGUKYtYPkbGdL1XMsHGemeHwMNt5S83t3/rSsxqnQw\ntnlSErmYSaqmpS/oHYB6SRdCx5tzPkw+O4fJtUpqa0XrtPyvC+tzA87h2a3p\nbrnduBWguXWlfQfCIdVXZv7jm5are56Wf1SWDMbjNcPWK4yYlAjLx7m1Z6BX\nWgGA41N+1lfZDnrHfQsCuFWP6kLXiqZ7cQujHSO1VwTkldBT+48XoD9XHGtG\nFR/w6WQDj9Cp6iqgsaAbTGs4tRYrufVhrXEXRJmN9OVrK+jgYte5WzVQJ2Ar\nHXKwVyJjzjbS59TnoeL/XWK4OsOzvoN9r/Al4W5ytGDL0j2ZKS+fgsmkZbcT\nqxYvycmBd7WOYZgrUs0onMe5/f3uFdiP3yrP5VUB4r3WZYf+bz+R8UcfNfpO\nSc9ffSsebcKTEjDftrgYCxiBXn0vWIkC+V0YlldCPAFi3bXg8KhB3G4VWTpE\nn5c9loc6YkGOGCNKWJsZg59/NDU7XmH8Q9JXlheSLKTYxCoqiNF95hvsKLE3\nWVUrfGHMo2w8cIt51IyWL0jxQ/YdfvsL+WnZWxzBpUreewPamzJO6ie5XJxD\ns4tC+21s+SKcyqB47A2F4GqicL7yir41SapsL+xO2dL00EBqTKs3ddoWCPIw\n18i/\r\n=aVqu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDbX4maTdBzRtdo9zhGac8zUYReBeLpjDrsZb9JJwCZGgIgZZ2qTQoZ1rm4PJmnnVtVCpoEqFT8pFhY5ij8fIMhi3s="}]},"maintainers":[{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_3.0.3683829_1591198711046_0.1441916887134005"},"_hasShrinkwrap":false},"4.0.4117339":{"name":"@metrichor/epi2me-api","version":"4.0.4117339","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","package:version":"for file in $(find . -type f -name package.json -not -path \"./node_modules/*\" -not -path \"./dist/*\" -not -path \"./loader/*\"); do jq \".version=(.version | split(\\\"-\\\") | .[0] | split(\\\".\\\") | [.[0], .[1], .[2]+\\\"-${PATCH:-`date +\"%-H%M\"`}\\\"] | join(\\\".\\\"))\" < $file > $file.tmp && mv $file.tmp $file; done","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"39cb00b646e98bad4547faed909c08c0153444c2","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4117339","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-kUSmxecwDBaB7LOyNEsaH4bhTw3o7T6I1tBSKSDJf/RUZdRi1qIya04HbW37wRp3VVktm47f8dHFHiHhIau/3Q==","shasum":"c44478acde6527507be9d50e6d585200c52784d4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4117339.tgz","fileCount":334,"unpackedSize":978221,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfX22OCRA9TVsSAnZWagAA/tQQAKOLw5wINexRcP1rAK6G\neoLVaNTc+d5Z5Lq+Uqet58s17CoT3aIvxCyTy8O7pkNYQNd6iEhNHyjH69X1\nd36vfVnh+1W3e0/TOD03Mw4LkvTlnWABe+dHSh3SEBENZ/So4W4saEC+gzDR\nlvLLTSnN9h1JdIAVFm5TkDNSVX6Vo9NxXTlqN7PdyAhlD4AkYHrOcCliAl1R\nnOXvosCxobic3pnIY1YHfkBOMcYEFelozPWlowmVq/XukJ4oz9kIKLfHYQEy\nKb/5IAUW7492xP7ojQOb3LmAszFkapt+8uwNliYBBhooACUYDOjJDLx+lNYD\nCZlj/vnftKeZPa6KckNpUKvgX4YqQLOTBQPHT8VewoMDZahzTwESCq3smSEx\nqWyHI6e5CrNj5Do43vo6bhrkL0tBVf18OsxHSoIT2gS8dfLGz9euA1pRxw6L\nypCXKW0NIJWPIkin2hT1dWoz3I3FVnRVdtcsTYBu5Y3lJTc7JSYOCg2aRJPd\np2qJ/txkJxlXH41VDHSO/4GnCTt4YfXouY1B0jrauiprorPxQsGOzcibc3Kv\nHncyKn+AdI42fGAm7Vt64feXrfPs8dikP57varRLRCmZlcJjLCX8NzB9h8bR\n+p69oB7/qbDFI985ZkJR2/gq1sOI3g92nZC2QUYgWcD5tm6Bt41PI87gFfqc\nFuOP\r\n=ZVH2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBWkcbTkn8jGly1cwtfWCBIp0Zf0IaJoq0gKIJ/o79/yAiBPBytlr07MjNDn0O1gYtX7GWfuOU7QqdAZiRn90BKqbg=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4117339_1600089486073_0.24399846147392146"},"_hasShrinkwrap":false},"4.0.4117465":{"name":"@metrichor/epi2me-api","version":"4.0.4117465","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"4fc78cae92ecd2025684ffbe389c44272219d94b","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4117465","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-l1ORi4SO1jwpYwgfa3o7b9XGUSxE5LysPsvLTCWjNeSu/u7s8NY8L4G4wfgL1geARQT2+vTrxNmZPe4RsFsjIA==","shasum":"4a95da50c863409bdea8adb8f2e049c94b105ed6","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4117465.tgz","fileCount":334,"unpackedSize":977811,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfX3OxCRA9TVsSAnZWagAAYLoQAIxBKX/TWZPBihzOKOJY\n26k/7PV2rsNX3X57efyBhjyXDMtWq4fXwwTLNhbJTmqZ05p55x2nDkTPEDAv\n3IcLyj7CJtxewpbbwjXeoxgjdZamJ5k4v3FsRi4guqX9LqCo+l56T0tFIaOx\nwP4FzkegtxujdqK9QfcdPK40c2tIPyQmeHtO0uofLL6E8T8HUaIwnLXWw+Ah\nxoFeuf6xD+YF4JrvPERyZQonTrZqQRBWe8tSihM+95J3XL91qNHiMGri3+Vr\nCwm48RXAf42ncmS2z6wq++GDSuVjdpxRaCTWWRRswXHiCmbGU106caLy+/q8\nSNn26/5sLcz/aqchc74CTBzfS/N8bUNWViJQcltNDtXYc1lbvO10hQcwcbe7\no4o3jlSao1YtBAhFPteOTKj8BJnCp3D/eBLTE8SAI+dcRloc9bFbm/6tL0oI\n7FtyxZCabyS2t7iJ9YbbD8d+/ofkg6EO0Q08fuRPB6WH7MB60/W2FG9osagJ\nfAOG/m+lJPpaF0he7yzQzQjzNv07f/lmJvrgm0juUrP4uR7tQ/M2RukfMhyz\nbY9kyROlOCMa0v+V0zxfeHyBchUxPMqypTWTNOGsPYqcUEicA9uPK2obdAI9\n9rYeM9d1SsHWIv5ovOgQIIe52b8O/X7Hn/cWq3++EYncJOKgn5pII2KIYbC1\nAvzK\r\n=3rLd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC8dcXfTwM8CgnSKB58o2CEZllN/n96+umvnEHv+v5rpAiAUq//gQtgwXpngK5M9NIYGtfdA4swYZUQirj61DmDXFA=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4117465_1600091057198_0.8605109228293459"},"_hasShrinkwrap":false},"4.0.4117484":{"name":"@metrichor/epi2me-api","version":"4.0.4117484","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"7e2bc802fd7ba14a843b621f8c3f0818fdeed83d","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4117484","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-HwpifnBnJkOKsMenpYUwjgFCVkPE8ZZCNjIUBYvRPfhmu3SKl1mgQDy35Z2fSEgV/DQWTjEXHQHCp8CCpdBJqA==","shasum":"fe91c9e6821b83ea4d5b5b93b71f7609a45a6fef","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4117484.tgz","fileCount":382,"unpackedSize":1976007,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfX3XWCRA9TVsSAnZWagAAdR4QAJRWBn5ZWQVgPMuEn51l\n84AGtHwRV+fbmnreErHx/TIJWW9RG3wcVP8Kk/BIgG91Pn3nsu5bkCKdsYfg\nJdnRua8yAa6IJEKOMcJIG2VkcNMe4PJtZZzhwivD5+YJk+m/b5hAKNNN6snr\nFWHzE+3oBX1uI1k/TT97RvLn2d9M1jpB6ZT4yeWA9Rsnq7bOlZRT075Yku43\nyKp8RrMq74FMj8Dmi9Oz5CjK2lUCW3e6MTaq7qtpRFiT6+ID2+zpZGYHv/l0\n5N6oaBH1s94/B6T1IGQaeihbrgJ+sVceF8Xb5+dYws4EanraTSsA1+T6aQyY\n5LrWFGVtR+20piz1haxMpA+/CnDD+PoPz56wUKQvKxg0YwtN4w8hKPSyNlZp\nH+wBTWqIA2Nku/b57U6WSObT017qnMeNV4r3PEwEEyJpFzmzSQAM3kQqFDt0\nIY4lARvgd92JGLDXRssuFPJiQoDYo+EjTXIACCgMseZPo8SZeTS27Rq/1W79\nboiYjuSELPDZNIl8OheDBtVFpZsT9PlbEaAtjo8FzdctK91WEqcav0T7vPPC\nuD4QZV+pGojfq2gI+NZ9Bb8P0WvfizJ9OlIjM5L1fWLaD5Dw8LmyJY/36npb\nmm+lMMKi1yUokav0PbFQ+l7U5574jgb7SBwHjJ7QIFM5whINF5xszA4sN1kt\nFaL4\r\n=pC4b\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDeZmw7xTOxSkSsLrxbzTd4bdKwERsz+N4pWsjSpAJ7NAIhANyvdQVWuXnbKvVl9cERiKpL/20dkaHK+6xnUpjRKJ6H"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4117484_1600091605725_0.06536032765575617"},"_hasShrinkwrap":false},"4.0.4117520":{"name":"@metrichor/epi2me-api","version":"4.0.4117520","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"718d541dbed249504e7ae4b5812d28b873cf7181","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4117520","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-JvFP7DZ+ieyW7nNTOqUzNt4HbVxV43urpN09NcTWkRomVRWIu2GY85ykfezEBUTVRmAdWbkdzaeRkp86v5jPkQ==","shasum":"4c247c31521cf0bffbc0a2bd744d683a072014a8","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4117520.tgz","fileCount":382,"unpackedSize":1976095,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfX3flCRA9TVsSAnZWagAA3MgP/0GhMblT3a8HPtuPbvcr\nk2jQJTKYFxeOwJaQbkVCTfSSPPy1x6ZlkCIDVg5X23CG6QljsoiqVOxYAz6W\nz3x93Pk7WasdFZBOkUX+hQrHJI5d/SgdzKYST0jX7sgBybOMVCNT8s0S62Ae\nFXVcZxLXrw47LqcRlUivVplJ/ppWQ4qVR/qSNjdrY1yqyHyILREzyPFffiy0\nGE7pXNZjQgzCoW3q/Pc8xCWyzoQMMXyPPBhq+sH0DbqHFwyuJaDhyrLCp8Tv\nmlSfRLGLjIaJgBUyA42rIlRKXygU85jHt8PMZ7hPCPI0cljnLrYIXxKQudPN\nHFYPHFh/JV+0p+sqgqp9pAz+6358+xs/80hy3QWb0dCcyDZ0SolFTBU4bBwE\nv/IKhcHfn+dM0jJThg4JjNyvSE2YJEoLZBF88Kojrse2CNzEKryA3pBLDK0y\nmcbfxyKTovzHgJI6IMNXIquolqfd15YGbpQ15uoAWfQrPTHy1XuMYWDTkD8r\nCCbh0t2gfXB+k3rtwFH0HLE0tDLsLCH4XCkrAe6g92S0lOpjf/uj2ElzztxV\nFbQki7rna5/sb7Vrezr+MvOilEriabrcw8BDbjSyuh0P2GIrTqxQG9QYiW5d\nZviBJC3BmdkMYPVp8a8vf99LMqf8UQ0+U3o5J6SkBTCBJgUnM7etLsQkjFhF\n7Hes\r\n=tOCZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA4GYztukPpLkYTJbTGpcxDRZLRtwjgmjQUOZB9TcOWEAiEAxP54O+QfRIDaa6pnom2pq5JExyg1i4/0Q48IaafqjEg="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4117520_1600092133257_0.3574929019785811"},"_hasShrinkwrap":false},"4.0.4118002":{"name":"@metrichor/epi2me-api","version":"4.0.4118002","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"ce3a75edc49f8d4fdac43e111fef54983df9327f","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4118002","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-CEylVhpNu5UTc679DaV1gMypYxH9WJBCOfurD4XVq+GY2kgDoy0OkNEdgpWjes/S7WbTYXV0SCSWqnG8dHgnsg==","shasum":"de584f4c2713824f06d3b81b60a89d5435d5fcf5","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4118002.tgz","fileCount":338,"unpackedSize":981758,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfX4fUCRA9TVsSAnZWagAA8xcQAJE9LHu2upWYnwPOrJHM\n1T6796myq+wzcTiXIuvGVXNTXs88uIgrvNh6UzDjjiZf+ns7XTR7eEivIPEp\nVQXpqgKvonek89yMqvjnbg6yD9rZbm3A5l1F5mo3Jwa//QG76EHeqBCEIA1I\nblWpu12RiwB89uGjJrzim6VX/++EsXOa3u97V46ISMhI9o0Qvjjxu7eoYnMV\ntzMTjDNyibz6sjSJpaxmGzC5OnRNHjF9FBFal3qyMgvoAN9hSKbguHJ5s9D/\n4RczIdWMlP1TB/pJNlPWQj0/6XzHojrer5EJkfjXMi7F6LAdDhQNIK2CWZnP\niiL/0kb7xLB8yN7ZGTruFZwQueBTtn5yqzGCd332WL90ou1EjxyoFuM0FA7M\nMuo1yqCmzKdPOMhA2+6UNoWu7nN3ASiBkotnGCHm6m6ZHZ6eMsTicibaByIT\nTQxCkT71hxAKlyk8WtMbUW9mUtGbdg79PrisimdadVMINzFGvoBS/NyGA++i\nP4RNN2iW0I+AOvKUxjNlvPAWohqpSWH3YO8KHSy9M5caMBZVxadu6AOxiq1a\nsGjO/I/sn0yJ4src6anYMdAJjcBuppmIlCXCKyh1qKto7IAX/UXAyOiE/tCP\nmPU6lbqoIvmnLXmX+4f6CprzaSz4XTKS2hhze1hKeOgL7xARMRYatzuAUI9D\nZlWs\r\n=i5vL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEPGweQH6yehwPf/RotHT/p65twxUrmv8FBTR9yQcPm1AiANaKKMurA48LuBnJiou1pkd5obo57waRoDX5ZJKVVLZg=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4118002_1600096211813_0.3465014675145601"},"_hasShrinkwrap":false},"4.0.4118479":{"name":"@metrichor/epi2me-api","version":"4.0.4118479","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"5b2c1e3af072baffb04101bfedaab8eb41242ba0","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4118479","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-RoLiNp/UHINaw/tFQhgC52/h6jvq0YafkAhs63FI45dexK3awmOGR1EFC2bLvdk+rSbM3bjwwJUfeUEaFF/abw==","shasum":"f960a8bf890d70cb3920e374e44e70ceb6a383eb","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4118479.tgz","fileCount":387,"unpackedSize":1987108,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfX5t2CRA9TVsSAnZWagAAeK8P/RUwniaIxtO7Kqpl0AU4\nAPGY3OaUqnev/1H2blIf2oqDE6xNwPjPbb43MxFDYp3e5Gz5qaXyx53aY/GE\nOij19nSGyxexIbtILj2LXPkTvjX0It13LqifMRLQkEFSarKQWTfMLPxjt5xS\nnYxgcGoCIZurZTpl31FkwOv50BrT5OunVjoP7vXTfIeDCX2r9NvfvdUJv+DS\nVc1QHGeFpZ3sqGC5uKsMil5vfaUyiNuHUH+mzSduPv2jp4jM1IVPTIdVHHm0\nsnLxzqdG4kO3+93adYyfo2RQ/BEttLJuiNcCGSEbUh+rZqBlxmGpX2qQxPQo\nm4WxHO7Qm/H64sfj7vUGuUoaB+oaKQ2rOuF8Hm8CRITbpOZduj4AyWRU29P0\nV7y6rYaw+bVsSendt7mmTyjkVos2YA54aSepgrFTGfkOZ8mUY3H/T5fQhT+G\n2+j31TmqfsILOog09AAw0Rq5CgAS4d4BL4KXkbVM4cVAq7q+doUAhA4ucsjL\nFYWIlqRvsxvohqbqktpaLfXc8OGO2rdWo7mRto51VpwtFM+rTcwahXGu4e2M\n47976KWw+tYNYXSl9LojUlKjw82eddstLuDgsgtpTMJTW7Uwd3Upk7UBOs3m\nGUV15s0h3lEeQIPkwbSQ96k8dy6cbkTrmzPAJYe2CQ4QlP1wXMW46A8Ona0m\nEfRV\r\n=of3t\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA57jLg70goWfzV0B7XZI/t3OfBnxZ70I9DlzTEI3t3HAiEAmU910pSWUbAIYDDm4o1ubAwCc0yQzMdLQ2jqKuYl97Q="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4118479_1600101237903_0.6452125415048144"},"_hasShrinkwrap":false},"4.0.4118528":{"name":"@metrichor/epi2me-api","version":"4.0.4118528","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"87ed484fad5e4f90efdff83c8bfd8be05e2948b2","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4118528","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-wWhaivsLgVYSUE/cXFzrFr3Fp2A2F0AficRf22WWjU5LIfM5HUnuRIMdLp2XBCIMUW/x0+Ua1kw7xRzTVIOWBw==","shasum":"62a3b8a63622d78f1c4fe0f1697e1b8c5d43e767","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4118528.tgz","fileCount":387,"unpackedSize":1987126,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfX6F5CRA9TVsSAnZWagAA8iEP/1AiVgWsUxlV3BXIOGT2\nALrLluIc0AkmnlqV7zcP7GxBuNrH5lxzbc+XRRjFuC3CHMeM/ZFpMDUqlV8m\nBlY4BW5uFO/6yMWGoOgnLV7VIS0qvALW1QmuC5mQD8UKmguYyU13mjfRQg2Y\ntQKwXbX6lcaGqDvZDJfCIKgq7eRBKLR7voY5YX+U9h25swmGVUqTkRCOQMrD\nlVh0UTuU6dxgw7e0bfxvTOqJOvitsWdRLfo+QwA+zzx6FnX9bVMBQTTr06sm\nmjEXjkFS9Pju6DRCKwjA2dJamn5HKDQ2xEVGjmCRgz9ENsLkAXM/8B75hTWs\n9OPlDYFlqyEj0eKqm2gC3GQE2W6mIpyGRSJrpLqvmgc+Cs0lLnmxx4Y7lo4X\n0uRjNq9guaSVq6BstexBOmdxTkanDBpEeUGmHCtWCSJsysRxTHu2zeF9k3pP\nVx4CXujOXGYIun64fdcoozAAEfo5YRDPBu0/gtalEsli+CC+7R++yyUYrQLQ\nqbe8rKvtYJIcchgNepBemJB397BpKXahSUrmRgaXutAuAXdiP+f7Xmat86bD\ndVki8Esg2r94Sx8WV5wLqDwOQGDdOF8UelC1k6690IQrbUDMMONU2YHVBRrZ\nZ35w+1tEUZ1jVR0S9tMG5DHl67APBifBFHpm/tdIVQpnAWcrMlyeRg+csXqq\niMtO\r\n=E89O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCGz9qtJdwO6DgCy52MBVztWzNK8kSxIE+qPQnFIhGYZwIgBQSGK5Yh8NaXpP6jCpb0C/5vojsZoi0ma75aeuMEvjw="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4118528_1600102777205_0.09571479517918458"},"_hasShrinkwrap":false},"4.0.4120169":{"name":"@metrichor/epi2me-api","version":"4.0.4120169","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run rollup:build","build:dist":"npm run build:version && npm run clean:dist && npm ci && npm run rollup:build","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"8d9ffd9a4a5570e41d2df413a0fba3478eedd6cb","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4120169","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-M+yayvrA+3TnoUnWf9OsDX28QNJNTDIFuVSq6+6nRbcHf9K6exh3AYht1IoOBWhhimfwYHCPJrIKLvHfmMGrvQ==","shasum":"a70ab8bf4ae8d9b2e53599159d2cafcebaaffaaa","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4120169.tgz","fileCount":338,"unpackedSize":982264,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYIg9CRA9TVsSAnZWagAAPdoP/1uS5ei0aFTp8IyP8DzP\nwIvtsakd2ktSzPHI6e8NBi6JBGI/AI6n5ypEM9s09PhKQpSWadEaHvQ8buOq\nQPNF66eETlCywpCr0fli+ck+aqzKt2DeLsP1qYxd+LijaTPpK8SCElEITlsp\nndVcmq0sPxBI6csy4fsSXy/u27Of9wGPY7/6EJFW+u2BCaqj0cxVejQDGXjM\nW9kHI4iKT+MfXrb5aUAKlsUIEgfeY3becK2AeOdrv0JklEZ0cTRXVRHHEvXv\nzHSQNtPotZCfKjEh6efyAMN5D9xxDV74CLP0x88moMDirrwMPFgT2ehQ+Yj/\nowXeIU/h/2DhAw1Jk4SxZatSuNPqPe139p4wfyKd++sFgN+rI9RTyA5p9Rna\n7cFk4uDpARWpbQNBOIIocMieM8cqGnec8CxclOayVeV8CZCdGMTIaLAsvG0/\nWHGr55QWQwThECt84CfrccHKtPmggy0eupJm95gCorhzlSnWgby+X7+lXKmF\ntkZ460AHZjbYTPU+Fyw96+Td1nFQmOpNrA9vqT/8+cBe6yPYZSPZRDpxh+LN\nOCSaGm/iT7E9AWC7w0lKEMYjiD18GztVyHsUkn1zkDg9gv+/J+KXgaM+ECpn\nK+QPq4JiUsjsO/3IcfGsEeSi4WRtv2+Cayagb1liJuZoH3AqdV+/DQ6r7aI3\nsUhx\r\n=a7hk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGgO9He7bLIB7GrWwz3OunlJpwwYa2p7EcNy+oubiSblAiEA9iitnpLbo/+ik90kUcZkVOGtFDQbqCwgIjYP6j2mmDs="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4120169_1600161852930_0.28586264652940896"},"_hasShrinkwrap":false},"4.0.4120508":{"name":"@metrichor/epi2me-api","version":"4.0.4120508","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"f32774ec2eddd386ee683a237bfd066c26204c93","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4120508","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-ONynYMamJbor5T3ZZmD4bdiQA2JhAQpxKZjraZS87mU6mkZ7++9NgJh4Ug48bqHMo+x2CSPwumcJ/fvEst4/Gw==","shasum":"d20390b3bfb4afa3f4b70e0dc17089efd617ac99","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4120508.tgz","fileCount":338,"unpackedSize":981982,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYJG1CRA9TVsSAnZWagAAHTEQAKFm5pfv7Z3JSnj5oOO3\n7ZoGn2KoFtircd5G+m+WCYGOpzSeCwAHFTkALrW85bq8iaVJ0jQyYDKXBdgT\ntA5j+W8/YZyL7bIeJnPoK2o/l0TuKuqwLqp8S9iCp2QVyEtOpHgtbobiRDQo\n3oEzj+iriPlMeWOgAYjasLQtuFc0AMxe7Z0KqC6VdDV29zFd1IokS+bIHJhy\nKT4pF9jQDHV8gn/QNJp+YiPyQeK7CNurqlea45PVfNU/sjGjR4iO5WeLZpyg\nHDFJx5NtwHxYM3RqR+4a82NZRHHOsT8SFS41vke1ncPPkIO+ukiYgcwzBGoT\ngrkb8kMJOaR9q1rhCh2KWaQQVUDj5Y6X5UPrzitB84cFKO6dGJvbdWbF8hHp\nf3Oa/O/oXG8p26eBXLVnIjUNJfElMR4Wlme3b/PvofzWpN6Et5EyuT5pWvDZ\noQu+kenXa/L8HUpJ0qWEuqeEMIa0s/JvHP/eydIKNUsNZ3AZGEP0N9mftWf3\nezNvN8/T7SohQGjPebxM47KZGbAEKjVgkPe/14DaO8Yd1YN3K9yY94rNw3vV\nWDubxzmH4XX1PWHGq9vmFF4LndwOWS/VVjjoQrbYwPh+zU2MPQ4Nl42GF+ib\nSHKh450Tv2nC11JIBpzRfTJoQMPTTa0XAbwEQTbXcF3sTbVswb9e0WgTR6jQ\ntRw+\r\n=pXXH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDIcvJ7k/+vwxMZfH1qTJBmFvyysz1P+bWWzB8K7ChHkwIgSNaEWWVZuiqt1txgkwUhJ0vFhyFm3u1o7eWsh1f/hQk="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4120508_1600164277000_0.7446867359523495"},"_hasShrinkwrap":false},"4.0.4120778":{"name":"@metrichor/epi2me-api","version":"4.0.4120778","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"e25e1931a7ba544b462de2bc8311f999585a9e56","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4120778","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-yh3xy1wRns0q3kmlzSF0/0sYhJVgANVGf0zI2N9CUpod/lBwyrwXZUq/uVKcxXgk93QW/x31mwjCyX2o0zDqgA==","shasum":"a20b96f5137e92673e526d23c5d2fa41145c5362","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4120778.tgz","fileCount":338,"unpackedSize":981931,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYJeYCRA9TVsSAnZWagAADTUP/iNPTHr3py+i33k1aeov\n2AjfmJaMEx5dBPP8GPcwPjmeJf0DHIRFWqKnrBY2y+OMimWW/0nY5upaOW1e\nWhvMujdRK/BEEWnh2AcDLJmDastxKC/ubKjcdSTQZsiWwcdhwmbnFbZIEXLX\nuxl6A6sSMSK3lE+Ee3AY+gfvqBXMfpnKoAL8yfwl27N2O/1I8NmqXGbpcw+R\nnXdmoCwGtjjq1xIccb4/WJFwmhyFCCAF2ijD6CWtsv8/s+KV64gmVwLiF9lg\n9ZjciMJnRQNukvHzJmE0QrKqwh/hAg1q1/IHU5IBwVRob4s6Ir3zhnDj1CaL\nSTrh+rg3vslHHAANDrQycLdIrDX3fJogCb1TKb3J3gDdBRTKwojznzhvKUUj\nJ2yvvUmKCDssTCtdAtDG4WViX9KJLOxqZBJxlkavg9bTx4qJtD+1Nn0yx6bT\nIbIlfzTAifIrFyVRLKEPm86OiCzljQILngn1A7moMSDZBmmOYOP2GL+Dctg4\nBg6lMfW3FWE81elW/BPwDl6ejWa8VHPi059oPwE63ry/xwPEy7Ygn41SOFO5\ncV0VpQEfoR6CQxy4ZWkLMSU3mCcVPFudkfjD90/ZGsbayhyyNTkMoVQP5CiX\nNVK86pMiaZ6goXIZMdpZagZ68Oj8pF2+Bde8DWYktQj59JTNZFPal5dF2nV+\nCBrg\r\n=bytW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD8TdHDz+8IQxHYFT0lp3e9VC7br7EQmxAeqNP+OchQZwIgN4PPj7D63cY1NJyqZPGGQavqyabImrnhSECE6c0xyxE="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4120778_1600165784101_0.45071730309778824"},"_hasShrinkwrap":false},"4.0.4120935":{"name":"@metrichor/epi2me-api","version":"4.0.4120935","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"5e00e1e762477cf0b47a437df915b2bf59c4abaf","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4120935","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-fiNcNZP7mM61k1RcLYUrxNM0FOm6X6bChA5dVLYcOzr0/LxbeLtLALh4SgrnM6Qz6E6LAt7iYTYVY1c9rLwycQ==","shasum":"74d6ad1cacc2f15c0a43c83461f66b460a0ba537","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4120935.tgz","fileCount":338,"unpackedSize":984508,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYJrDCRA9TVsSAnZWagAATAkP/RkDHgHkcwrDyBDEcN0q\nkzWhnbOgt2V+RhjUOW3rvzzNwl5vPwfEG1DctZtpgTP5I2UTrOEhe1Ke3Fs1\nzaf2bxviKFWmBdQaNbLMEh/J+e6wKsH1mQynljk69wrzK+ZpkqXJh52C3nq8\ndIRgqbOnFrMWmaXgQwamQUOc9T0ZI8yZkxhdaNk15W9WA6+PIEE7y5484N3S\n40iIxFvVr2e1YEMfVej85LaIuAumJ6Uggx/PiRSp/EOhw80v9cguEe5Xm0ao\n4ItIFjWlcC4Mt185ZLjrp6QlR2Wy21nFI/1zVq0uXMH75m8FLkGFkSk2fCR3\nvExG1uGCK8vAg90zU9NTiORxlFG6wOv47EXo+maNhJasYaG1Owp6kqmS1/SM\ngUD28jNXkvpTO0o2VH11C2KFTFomLAqclwtZqDJJ35PjctJtZR+9LEZw/ub2\nxv+Sy120904tWHlq9nA2zfWh16G2EP8Ty61T97RJ7qVJYk7fUGmUSG78QCVC\nCSgC4PgOPqAOdPdZKArR0fM4IthliKCdrv6rymOcK2i5ykWuGmLrT9xjxSbe\ndgqkNh6VV9Z3c/K7oFdsEsfo/qkdIVql3BNRCn1FOoPqX44MpsUHVYHuvMHi\nNk4M3B2KGI+6BFQEB/vmoSnO3hEE2rstuzsN47eDV1FwhXJgAtyuX9O10Dx9\n0wbg\r\n=PyhS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDHUjw61z5QAdZZVAYn9QW/SMMyeY17eHzzrasZudM6hQIhAPymgWRGsS4YvbS+LUZtx/nPQMDYEimMYeCFEXSZb9z6"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4120935_1600166595463_0.7536759987310118"},"_hasShrinkwrap":false},"4.0.4121231":{"name":"@metrichor/epi2me-api","version":"4.0.4121231","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"5b7e63b46e63f0d3e98d7eba1f2118aa6c0d6813","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4121231","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-OJnWR3GdVjXidCIPkupNOuTi5BpzVG9HWwE2r2rNpnVDOsaxL6g6Z8hNHhJ9JlAvtG0M7LNZSiexL54m2103gQ==","shasum":"85289ad868b947d1207ef5abc5ae954d9d675cd3","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4121231.tgz","fileCount":350,"unpackedSize":1105095,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYKJ5CRA9TVsSAnZWagAAgmcP/RBiyWhTjVgloBGqefed\nKAqzlXTmG0F0bZsQNJ/gCtJPtd6ycNsq6KGDjAURMdJyB8bLDAMkLmKZ+rp/\njcQW3q7dlMFdmzfTF/cxaow77iS3PxXgDfnEGVu+lBwfuVFXOazU7lr5GcGe\nEyPTnICm9P326zNMWTLmOD/QcoTw3WlY3a2FjPhDn5FlOCwU3a0torsPKiFd\nSlX3KI3qKF9XH4N1gx4tnW5JihExGIQfMC8XCRWyCI83hSnGTi9/AB0Mqn1r\nHRhiuGbq+f7sGSc9crRVsrKXQrDOkCu6pG9Tmb5qj/5OtX32hqPWvdkCigEf\nSdqKVNPefquOfbU2q1CmPINVwhSrnkUEyHIXXf9pIlDbtUaZ745I08D3h1oj\nHyGzlb0vavcZ1HVI+q6XKjNWD6IMGOYExGLkmT12FExOl+o1DAXxeCRczR1V\nST+XioT6EvFyROwEN0UdygnduH51IC/dLSppYqhBLerAO4FNcPc8deoiRKdG\nYzf6ZZUpcoY7TH20A4Bi6JBM/FNCxICpnJtWXu5UieeOpXvcUG1C3DfXOFUl\nyaYEvWeaxtW9fHYnpP4FfybrnbLqLbzLs+2ppYbEwWEJFygRpZVJXyFgF0KX\nN2EobQNFALyJOkdSUh2QuQY6evMu32Z0glX0CF6WxMwIrco3GMaVzIHEunYi\nHiC1\r\n=TAVD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEIZWeQhERgYbzvDpCQUFnBakElg6AnTyNNcmEOcCP/5AiEAtcImNh8W4dZKqhffPiLAUwSdAPOQEveQgXJGi2BeLCw="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4121231_1600168569043_0.4618724596201149"},"_hasShrinkwrap":false},"4.0.4122305":{"name":"@metrichor/epi2me-api","version":"4.0.4122305","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"a0c050d1cc05134c3acbbd4f90b4113a347b1153","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4122305","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-KgvqIlxLYKLnJ0ooD8MoQS/kSf0JD0jtx0+3R4yJ5hHwwBZh2znTGX0FSnbaKPAbUDfIxaDGugX9xWt36SLW1Q==","shasum":"3f2ccfd67111ef1f34ff5561c98c2267199b5ea6","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4122305.tgz","fileCount":350,"unpackedSize":1105087,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYMMxCRA9TVsSAnZWagAA4soP/RKCZrVaYuTpSrdnwmBC\ni41b3n+9sp1Px+z1AdXgef6v9OKsUzPQtps9jiTQFYr4DItkxI1MXzjds4/P\nXBhk8dptU+WuEhNS1drduBQKpF/VUAHc/ifVN7IOy2FWzbPP98JimfYw6sjY\n46S+t48j1uwxyRLc7Xq797BiY0CBaGaOhnRaVcGaTnZs+1XCGt5uK/wTbeYI\npJJxmziH4QboJrSvWzuCOvBdyQk70MUuYX7+JE1wNzRYcS9zWs7aDpRXihDk\nJobd+YAxingUEU7Ea7EKC0MxGNMaZw63VIs/sG1vKT/Wbm1wyJgVmX5LIT9F\nIlVoM12/sNZgZPAXR0AUMoqzVeKIS+qJDvsN5Dfbf1DfILBSwOplxcM/5Oqh\nz6jfGwm9FLM1o5JfxpOX3WFYYNjGw1RaatXeU4XvHwHqeXRLuB4eA2D6JF9P\nRpk1Zlhev45E0lod0rsIrvpo8aaaSVmlnCX/pOhUeSQA1+u53CMi8qBDUHKt\n+iYUQBEx+ky2OQbhWYMdvClXGNgxAyQbB1p/03o2saA6CHHusJuzlyeaRtYU\nROYF3JpTQnsIwcWDmzmokYTqcQS6ISloE8lbRtdJ7C0vZhigsRDxKDa7HQlP\nBoDJIs9XaOMF/dlsIHq9fKVY3EqsGv5UuxY/s/ZE07/meSRQwIYkYgCsoJWL\n8B6i\r\n=aIKX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCcsfEfJitJ/38eXqFqZmphgHpDwkFSX/6zmc2JS0MTYwIhAKRvwODUpxCE/FpTqmuSUjWL2io8aNg3WLArJ/ZYv5M7"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4122305_1600176945029_0.5504144513833678"},"_hasShrinkwrap":false},"4.0.4123252":{"name":"@metrichor/epi2me-api","version":"4.0.4123252","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"665bdfd89190cd88aadd0ba0002c63176a3dd76d","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4123252","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-58UwpHzdsYw/Zn/t/7l1lcah5epYfQ3k+XOLFDcMRMo8Tlw9Rlkapciz5MyaP9tbbsFGEP1/l1a1YIhaY9HDqQ==","shasum":"2c11ee7c8c522ce4c90eca04e64e217505d317fc","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4123252.tgz","fileCount":350,"unpackedSize":1105193,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYNjACRA9TVsSAnZWagAAxQIP/2dQnYS68gBZb07bjqhr\nA0AMw3tORROtc4I51+Cs1fYTRRobUfOMJRA65uUA+uRXr6Zz9sWl50TyuHGw\nSraX5pABpWwWgbUwAW8csm43rXQt2I17k3624GKTphDR39sG718OtKjOGE+u\nC1QFokf5GWup/21sPxXjk3IHRSiPjGjQgo4Ic71mcmXF/Ws4ufYJxUXgeYWl\nkUwARESXPrDazACswOEbiv2gAY6HMCPy+uKrg4HpM2cR5YbKXXmJSGbA2AHV\n3GI/Hcby7ZlJY1ZuxxrQSnIEDXCxXSIDswNH3jn2G1K7pjBdsyaGgsq/xIFo\nJ3jy2V3+gI/qqftb+Kytm/RYrPFZ2mRdwHN5EjIKbcT56rg4nOVVXShG6JNM\nRnbbzZ07abslvwDdtlH61XDFXibzQQXApeA0J9WIzBYdcwuIgcBU45Tmtenh\nGqBZ5Y1AIn368BWrB0e8bcbzXOUI2Y9BKwxACwoIRoNtIJfj3wKHspJ2fcv/\nN7+hzWHKSa7MSoSyoS4YsN5m1a2O0SIrIOKuV201yqw6umoZHg0iOe38A8lu\nTnQ/DGe0a6CXRkztTuCFLmLUvndmFGI5Uiw9awQgYtDaHOQrtZwktX1spPUr\nqxgEw1poz82FSbwg11P7GxykerMC1FGxC1sw5/LMqObKhJYvJhZC9gZm62pA\nfPlI\r\n=GoaL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHG3u3wX49YgUuCeg0ElYjMmcSR3xKGVzkIpojvbY1JYAiBlEj00TebRcZEz5mhLrwt0XBYh/9WUHSJzAdiZv6SdGg=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4123252_1600182463810_0.2769885310025093"},"_hasShrinkwrap":false},"4.0.4124924":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4124924","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4124924","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-3L9GDsgxsPyX6WlzTu0TaDDrBadIBlBb1lq/H4HjCLC5JEuPBmzCrm/R0hQf4oPo2hjtwtA/hnGgucCONTSpPw==","shasum":"6e74c36405ed75b7fcc8032fcba2e485d234e827","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4124924.tgz","fileCount":182,"unpackedSize":5197559,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYSPMCRA9TVsSAnZWagAAVT8QAIWEj/hkQ7dO34E2W+t5\n6dFcZsGvQ+iB0UiKQ9wT86ArTtPZ4VxRq2ctbOBxeS93vusTzZRwI8pgThix\niJzMmjGOWGlZQfvRxvoodv8iU2N148GWU1LsJikdFgd01OAeGcEfX6dyzaHL\nRkMAplbNoTHCN+v3BgQnU6Qzn5bNi3nIB2mbd9M5U/KkAGEJOBU/q2pE9Erp\nkQ9MfdZvXK5S81BKXUsvxbU0UnmA8cF4NTWuWg1tITTjBXubnbDYspQhp3B2\nLla3FQvNqX3qX7lF3d4Zf60SYxRlUZxmiuWo1fE9gBIbGkoHXkj3rG+eT5jo\nmEFKV0e6ZveybZCCpxwnRhMUI9A5sXw2sDHk6zcDrbiiiTvLC9MjbsrMVV7p\na4Ofe3jwgbBsaOlQ7Qw/39AmH1CFDEarX5gPio+h98JfW9haGGkZNFs804Hf\nHvwiGFeo1rRtfWLSFLa78qkOjdFWpHVoKsBHs36oc8tt38R8/2geCWxE258+\nGsy1dQbxjTfYsZ7LbjWGMdBAbWiJabO3pRKeHP/UO32l4ri/upRRF+qIwiaN\nWE1DmUd/wF4/z87IJiHfRWgHDWyp/5Souuwst0QdSQHRJ8JhSVoPctRFTNR9\nC7B481h50EXbYT/SbgFddJiAch5smY6i72VZroDPgGT6TFYzAC3jnMmSXa3U\niYE0\r\n=6XyW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFxlcP1GgmQCRCB8pPaM+aZQuqkVq4iNxPVcYX7gFIWlAiBcnQhD/Us9FKi6Jww94537T7Xl5Ars2a2e37LHQbCPxw=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4124924_1600201675480_0.7823968411383322"},"_hasShrinkwrap":false},"4.0.4126560":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4126560","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4126560","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-SXPWnOQf/bFnaM5oQ2jpB7G3V+Ejy0y+u83M2SD51NbnkUaI0UEGVokrFN6DxydeaLqQrfL+IupAnN+/7tfc4g==","shasum":"5ec20e1013135f09fe6ac2538d29a4940d7cf868","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4126560.tgz","fileCount":182,"unpackedSize":5197585,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYdZvCRA9TVsSAnZWagAAULYP/2ZaG1tdWD3Uq4nli18H\nUy5iA3BiKcC0OEH90t09hbJUl1s1kAf/SD8IAO5aTviMGdx54pndgqdg6uO2\nss+d3FkVflk8Q28QJbj6Ek/ZXb7CNGoK3L8AouTBjfXERjxMepwY7IAu1PMl\nugeBZOUAUiWpe5coeYGVU3lhRRsl+DEn5m6ON0TyD+oiLql8nqu9/vek8hJl\nmkpt+nIZ2WvhbDjaaE5NK5ftGJ2wRAJo3PumxN19HPNUNpfkJlZsyijFZxp+\nqZs6V9Itl3g++sPee1t+TSkYuC/oiXCifjMUSGdjCBR6snhjXWyiDVSVgjF+\ndoQYIZ+p0DjC5QLiAW9h0ZGLOtH5/PdW8dfcXzRtuvjZQuddm/zaGNUC84H5\nHkpnhUvDhFKVPQoIUbhhwGeEaBCfKsYKamZSEdtL2P79LnhGflhAcvj2zxi/\nj8NqnadQEmXkrq3k7nd/Lr2NjyYKhU+FWUTaWaaso8krc0CskEqCHWXl/mlv\nFOM2R74db3NTPR+LuYtKUx371OrMV+RDv+kzlzmS9/R+cAQPG7PSuaCINZCR\nG4PYVpgAUkDuY/HTTpdJoEnN5nB1KOXxAnUUamE26ozdy8n3+0AeYbih+Xpx\nc/1GAfjT67YkD6WgM6OHGXmF7n+4b5F7lVdmEXWHE9DFPl6hvVCqGvI82dKd\n9wf/\r\n=eh5Y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCvS/lG1Y8nMKOOh8WoM8jmQ/l2RNNiWO6LMdpzLNuaDAIhAPPlIhtSLTBXVfjX7A6k+3vL9rv6CxF5SISGBAoXDbBa"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4126560_1600247406610_0.336867699317958"},"_hasShrinkwrap":false},"4.0.4126815":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4126815","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4126815","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-5vzyLPp8lEqLRDZIvA6GDbmU9nkPulneL2HJtS8hx8VigCGdu/lC3XS+9urnZVk/JMpRqM/0fStt0QzV9QANrA==","shasum":"6606ad21534e5ff857d0e8d925c443f6171fa233","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4126815.tgz","fileCount":182,"unpackedSize":5197529,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYd9/CRA9TVsSAnZWagAAIo8QAIUGoKgBeQXfxPL8no5z\nyXWIJABxtUKCNhXHUCRMboZ8vybx55tZt/1ydi9uqUUZhHKPu1klrchT6peI\nYgPh+s+I1ruiYsMR5nYuPY4oMXrTVulCbx50KouSuQGgaZb+kewiakYDpwwo\nK3EjlXniBSgz59t1p3V+FtVnCAC+cRzzdTHQ9EWYRUXcOmQDRJCre0JGziQD\n5kvOdjRmzbrPyAqbHdTmeYmQoWPcTQA2hE7CleIRq3pC7QLGothxitWls3gx\nwve2X4BhL+wOWuwMWX5I6+m9DOGdOXUUBSTKL06hWBASLxG/mpBHkrqzC28f\nsHUlteu0ipsjdxkRcrVQ81tNyCOEetjEZEnycx8g0YyvLBkga6M8+LGqZKMa\nsLmZOaMpMb3fCNlstP8+M66T/LOlixp55QtXG+1nur7oAJSsfmltOy2B1Yi5\nWg+bkFlRC1F+0fshqO7vUmU8qAjVJf0tLOe/3dh8gl45zMdEpHbF/5a9PA8t\nlXjSkfn1BaV2rGGmfSH3LRYhoc+UkDf8zXiR3XN4TqvQ0i0JFl/XOAWJPRgc\nv1+lxlCOxtdAXS47IR4Z/Zly9WEYkYSttUpVknuFzXz4wClEYnuUx8rINOlk\nfq4kr7YnPo+/y1tgp7qawD1F5wL8vEFuWnl4L8BqXsFgYimp5esawdGrj7i9\n5L6y\r\n=W9e8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDoQ7u9MHP/Q9SLIsqvPvuerb/ghfogvxijqokcgUkOmgIhAImt0VChXp3UagPtH8++Hw9oMKjn1mnRusnzG6vObwwo"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4126815_1600249727096_0.771064175010705"},"_hasShrinkwrap":false},"4.0.4126910":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4126910","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4126910","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-FLz5bC8Cc79gMqsePPvgIsRJMjfR/p/9IcX88t3ronjy+58TMz1hAJhC/37WXzJ/U5GyVY62DCUj/ZWK8abTcg==","shasum":"d1dc3fdfa17480eb803ad0d74762745b77d57257","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4126910.tgz","fileCount":182,"unpackedSize":5197529,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYeNcCRA9TVsSAnZWagAAnHEP/0br417yvL5twtUXq9zo\n7MvEO2yElbLO+z6kGG/t1e2Dt/Y62atP+BKPmYKmC5Mq/CiFWK8QHPX4c3QK\n5G07CzxVwf6g5xfNLeZOBKwMKwSQa32pI91yuQWiBTHJVsABjEZFD9Z0i3HA\nM0NV0KvYdRf5698zcCXUK1/dJyzq+kHpXbyev3yYQ+q1M5lbdbSFFDbRHv61\n+bkxLiFEBFlBfwfAKCcpPKYGP8ow6rDORycJMk3n7dL1LSdNnl2KR5GNFsqQ\nAO8z8DbNaJiwluoLYGR5pkPini0H7iMn+Vu5V/xmSnk2dgNWI07VXnBBsc4u\nkK10liD5Th5rjAhjL1yfCYske0A6Ea0+81Mybvif1oqCjMm12PYd0oDvIUCi\nFYjlrYE9y/EFb+sXX/wTUQ6kmInTUDT9WY0NbLu1P3d7PYi3i7J4Sug9y0OS\nTIF69mHegxMglDXCPtCi04FaaOILRDaTRnvdYJzGUvVZrq8/HxKx2cMRNVE/\nV731BN1kgCDsT8PO2szfKLcLFqpG29hEI/0Wowz8kP4lK7ONcQ0UtdQP7/zu\n/fnyUfOJYJNFTqy/gD9hvlvz/D17plW8unOWLNnL2UFBxKIgwb6DTbFU1t88\nktIjq+HIlYGPvdeO9xwYFJ1G1+0jPZMk7bSO9p8gxv+ENcnfM/f/7VsHWI+t\ncwnh\r\n=i14q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD1llVkh2UZzBcW6zeuBzhkwPoJZSIV0mwa9nIEUbMDeAIhAMg45yuRbrl0cBLekxZiGVJlWL5d0gZrEUGz3qGBIz//"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4126910_1600250715572_0.053900852278567335"},"_hasShrinkwrap":false},"4.0.4127000":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4127000","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4127000","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-r54uTR4YsutJB+KSlXb9p2pAwvJPC0qXiaFn/+eHFjXNEXGwwdIxceIHxV4C+zg1x3/Wjwl/kDzR4SSO7MMD9A==","shasum":"03d23c58f5f46143c820c268be7103899f10dc98","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4127000.tgz","fileCount":182,"unpackedSize":5197529,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYeaGCRA9TVsSAnZWagAAnx4P/jOqnN4fnIN8lvT7kEnb\nQA25vONd/h/gsAr7AHBg3ra1zYK7vIuJGyMDg8CUTfByLtACSxr7JJ7aeWXN\n+uvujI0CH/24YmC8HZlgYmB54Mi12Ols32bZJxz4thnc/AHDYbRnvyDdyrTr\nLw0oz6MVJkrkTYF2M4c4Lu0HjuhCbNVhnAj3f1j2o/o9IoGqqC2FiZGtBdvI\n3q/VfXKkIXCTf6+4PqmkIsnWO3te/tNP8dNef8TQRWyk7U3ohq+BEGb0QtE3\n9QRT1NArl0KXXoklp+IXFnHZlI4/3SBYsqpXWF7mO296/a8g8eWUo95ylcgB\nOlh+k9baFKOUPaSSK1VwqHL+RdzrSKhFWid0u4fEK/0kNaqyoSl7+foTX4z9\nkaSkCRtXZNqs9GhWo3msJrGcYNyOn7jwMVm/QgTn0Old2mdnuhsE3YtuPRV1\n8MxceVLEnSIjY2ATuSi21ypMmo5ttYxIPjthpldC8P8d6yPvp6M2c/wmFfGR\nfjdMBkIpTGmYFYu9k3OSMu2NhTeLH6V1+iDB1RZ6g/OMYbDpZbsZlKB5leu0\nSLwih5Ky97+MJDymAbDAmVbjhlI32+B0iq2muyuG1WHPnkNnBcV4dAxNkPAU\nUd9Kyo8/bMlGmVlL7uIQfWxUCGiPkh/bJ4UrupIJVys28l9RAhOwSf9jkuDC\ntfiJ\r\n=v8Fs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPf96GwWjaH9kV8gkaVikMNZvFn00Idq0KNk2barKY8gIgLZ4D67kJPW2ZX7obtSGstaS6xqaHQxg9ZMqAVFB2ers="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4127000_1600251525772_0.8773442057638761"},"_hasShrinkwrap":false},"4.0.4127128":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4127128","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4127128","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-HY9R5NCEChau4QPV/Ju8mFcrXPvhdRxKY/dG5SkMSNnuu4yenz+jfFIIMlvvXVYjiuzNZZShBg4W+AWTEI3MTQ==","shasum":"81c98353e8bec768242df01d823f9ca328bbf73f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4127128.tgz","fileCount":179,"unpackedSize":2061685,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYeqlCRA9TVsSAnZWagAAVewQAJNl+OlSOY4LPGvS/ZwB\nUIKqUXl92Wphhu1RgE0Tm3imbkPL53E/bmAmVXtT0E4mPMUGt/XmM4VKWoL1\nz9vE84YRtyG8TO1wE+rnz9zukVzfv1fbh0XdngvNhG+yVP1AZgJnJW/8esw3\nOm2r+B/undctAyWZ0Et1sSgMIExS/p1MXGot9a4XoE77mF/5rnmtHzqa0LuL\n7lUi7g+lsH8Gr6Ei141lDAOSGRMDUa/4aWPib6Z+lXaoAktkbpWRRCPTLtwq\np+9V1SqBNsrlVEbnkPEuILUM8RZEMjFtMo3RIXfbSocwd7Y8vHfQ/cmoJfrb\nAsQwuOk0Y+cDojaaL5ydKsIxtvEOsbpdB21BxlsNG7X/vh5ur94WXg9qpb8u\njEwYMaQYFHGFkK8HLb2X1cBTXgJBfS+/LOzJuTbqWpfGHmIMOkQ0mTgh/VA1\nhi8TqKAQLoWXjy0McuvW7ogFSvKBgcc40eZ8n+UWwOmh34oktSCt9tVZz2je\nHQpNkemaVJQW19sNqI5dgUplFofZ+5wVcUf9f03TyhddDj88bf0J7R+B+CQw\nr2KuFB56sx13ASWX6bf8ObaY9Yg7wbQK/A+84jQAPzck4J1WGtrhN4CvMfXF\n24SDlETzjMNQd+N8hzs+5n5zCTiYcoyz3/bkdMikLlUKFNbW1REBiyWPqB0Y\nri7b\r\n=rMZ8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBAcsIYkpO+bJ/ezOF7uf36Kk396FpxPsjF3v1Slw9pPAiEAze+WBewzJ3mh+c78/VGwITuOaQh3CdxyA+R8mWY/lak="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4127128_1600252580793_0.5719453824011709"},"_hasShrinkwrap":false},"4.0.4127700":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4127700","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4127700","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-7hWvTpKQZe4y7h7IjMCUPceQg2eBlTucddvozazRU6Xf4L1m0v2a08C68MyBBZs3sMxvAjbMFI+7LUv9Z89QdA==","shasum":"33733b1c53e6389ead0cb9c7d282960300ba00b3","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4127700.tgz","fileCount":177,"unpackedSize":943314,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYfwDCRA9TVsSAnZWagAAU4sQAJz6IfFeR1mcdsnI6G+T\nj+DlrfcrpppBzeU4W1zLpC5v5vqa2bRahIJiq7jsglnryn4OY9noiQ4wP0c6\nvsKWjpaAVbLsiuTt3/fhzdXT8lIuY56DIROQOq3d+5Ry2KOCr2u67ucLlNDr\n+5NrlbTIl8RvjGMi6OsvpxbkI0w0z/w96jVVPP4gAguQqdgQ94rqNK/Gnj+G\nudB9wtmeePakOrpbtkEeA9SzBem63ozbf6+7QqOhih6F68kumXio3wNBOOYi\nKn3RQiPaNK1UedQLdN2cRAvMaZsMy4SGPvMzHCogSUJezzzpYKWrDW8SYPge\nRURD5cAiw7qsT5FztlZoYS0DrkQ0zAn9SW49eiXXxhvL71Wvurq8lHZ7YlOw\notd2twvR8Hjys/ndNJpLcDmD0QNiko1a1T2kTIS8GXxsV8E6tbjNv2Bjl2Wx\nnOzughupHxy9+GgXFBcpKzzJXdLPCgfoyPFYRFVrvNANP+sLn9Eg0ArYZt0y\nBIlvsoCu/hdPJXHCLds5X0s2DWq8ucjCoE7VrNkfk26Qjc3o2fjZMWRRCMHU\ndgLs73MHPaIA0XAg/CNtDalnOLusJmV/B0ZsvF8jhdrKhgOcJE1A4qb2G3n6\nB3djuawI17f2R0OxIH/q7lC1u7Zjhsq11bjqRQKtFRhFmhcr71zOEuETI4GO\nzwWF\r\n=qKZl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCKZrtRbvXMftw3XInBKkWzCdOlqd3joSJn7VZdd4YSvQIhAOsEwkmgomXVq1PSGm6FNpdQqmqUU5XLeB0GLktEgq4K"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4127700_1600257027075_0.31589305425903524"},"_hasShrinkwrap":false},"4.0.4129621":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4129621","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4129621","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-NbCciXTLE9x+zmRxiQX6W1UJpMpiHMV68T6OJ3sUFx8S2em1qrb04vxEoTu+EVq9tVcEx8WqE41j1eukGRHh6Q==","shasum":"ce7593b4756eb88e8ee2010edf35f3c6e6d0e690","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4129621.tgz","fileCount":182,"unpackedSize":1695605,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYhoiCRA9TVsSAnZWagAAG4cP/1zsmf2q2W4Y5jN1F7SK\nzT9NFeEbdjzgze811xL84wuQ0qLQyDh+G5/c/oXWL7XZlQnQI1tUsxxzEQDt\nn5ZJx2t4bhQ370/UQDCRS4klvT85rHXU5o/tYo37pgFsIJiBpjGSSXVz/9P3\nVlMEQNiae7g010WW3pu96RW2ww3XBP06qYuVoFngzV0CktO0CSj70EZLKqZj\nlJKl/JKjfC/PfvIOrowBw9C+LEwWPrSpWY7SUePZrIAEZMGhVQXif6X+AhVt\ndYkuFplLZILy6hSkXtiDsXRobKD2V1PfOEoKmgzjutgii6tEkJg46W6qgzE8\nJOGiJtQ9QOJFdig4p9Ikyg/VHXgVUtNmn/eLcQMYh7FyMTG8vW2nUH+Cp5bd\ne848m9lkkDPFTuOwqwyyLJ2seBa7DlxYd4j0xzk68ZKuhnEsvLqPJmivknRf\nfTkCkWCCSAjgmFjfx4zzIQ1PW9+6UWcHb4FdJnxCzv0gHFlju5RvWsL+14iM\n5wbEF4mDkqKZjl3m34/xyFPmfI8YM+Dl89D0jZCIXmiU94W5HCaP5PZhb6LG\nFlFv0Za+FsnU6F+t0djFkhFV12fRD3FUlagZpu7Tc06DsLazMsZhSKSIfbDw\nELNVqXj1VIj1eTMmrLUa1pt6ZMOjqbMFIMkhCLb/DzqMYlzhZ0nDZar3zKw/\n8Q1b\r\n=Jx7u\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHV09x4V2Stllnn56NJexchVD34uKdZC2YOGWuyKg0jqAiAavzhqrC6uY0BLqHZySVjs0psc472JqMiUpAzAz5E+aw=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4129621_1600264738277_0.26707837323363304"},"_hasShrinkwrap":false},"4.0.4131210":{"name":"@metrichor/epi2me-api","version":"4.0.4131210","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"170b28e2d1153519551cf76a58b92f4553fdecb9","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4131210","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-UiQJJNUd+RQiEJrLWmcHEGzmu3K/NSP/Ix2kEMrhB/PUUM8ASiCjTXVZ45+MwaAb1/ZsqkkxJfaUNcM17L1E8A==","shasum":"ed26027b6f3fa6e4417a0467f62a4ba588f1af79","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4131210.tgz","fileCount":399,"unpackedSize":2110541,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYjsDCRA9TVsSAnZWagAAlMwQAJDtnN9hao7/diBPCdIf\nVYHjI9Ex0qdclYNmZEcNLobYy744dIWw84GO1xW77wF3ZWT/aHay+hJpj0ha\nuw/CI8c68Qc/XhwI888wBlwOU2KUsJaMR/XlT/kj3S5TFstSncL8MoatW8m+\nlI0DTw4T6e3UhbE94PxRLHugF62LSdYwQTvauNTUy8tKa2UkB2XsSW70Eux7\ny28mruyKGTh9MPbFGSfmxHYakTqFu5NxBmu/OpwvR4c1zpbduYzSrGRMzGJm\npI5y/9vYuZLxDusAur70NXarlMCQ75uoUO13eEOfGEd2wQW5yMB9FHnCTMgw\nbLnj7J3xmKGUdayOMkUuZZLVx+wa0A1MkmLtsIfz42i1NDKsxc46f69wges/\n1mdO6Xp8H2C/bfTVJkGtVz0XgcXYOzRj52GmP9WyfPJBvYA/Im96hbfNVgk+\nqKR+0fXNr4Sdm7IM8bgHEikTQXSfOdYnxPH1ef/EBidojRGYokj2alFMK3bF\nVQfvETu1g2y7zOy+rJhkueoE8z/8RxSYN/Utw87h+9jJrX2mAIE5Pf5qJWbB\n02f7J4qZ1uRnWg+rZyoFcuVtkBdFBzK7Hdl1VPDj85hwLmGdULHIi/CnpELI\nGNaWTTThkS2n2ZNcYheXfv2denA8/3Ib90MHCUn1J1+QHWsZdkABibPumHOk\ni3KD\r\n=2uto\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDRmkLcIrPA2zZc+YTQOBHW78MyT3dwH6OpOcmyKjqTSgIhAONcgsxalnheSrr5RLyGMuss6Z/GqlJdPA6SMzbXzzbw"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4131210_1600273154641_0.24085844959846225"},"_hasShrinkwrap":false},"4.0.4138326":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4138326","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4138326","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-SMe3ljPPDV9hkfje4gTxsRGO/ECViI1KpPQ/ZwekJn4FUBpMIA4p0pglnxPcEBKZijP2x42W4zIkKgzF8MBA+Q==","shasum":"df59576ab0b04b0106786c25fe03679fd2da6777","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4138326.tgz","fileCount":184,"unpackedSize":4239319,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfY4CICRA9TVsSAnZWagAA/v0P/jtuOGMfgftXOXKFPcDV\nDNE9/78KjM5nThbvNG/kUVqtgoAl1i3M2F0HrHalrzHmki320xA9SvPxITUN\nNRUGTZFEQpU3KIaPmaIlHeDCS4HUoAAdttZ1FCq7eXHUyyuAAO/8GN/4yNLN\nDLPVWfGo3ERzSoy7i71k2vLPAUL4EkvJpi3HqBMDR5Gj19ontvq/u14fbFjL\n75YqoGx0wESZQv9aFyol3Scr7GNuw4gjZfbCN2PFK+yRmAglELLWeq8r6p7F\nKfVvOSkWa1VkLQQbFQC2Ti5E+cLvARJV/nUrbkSiASvNJlgWnhzIj1kJwP98\nkNTdf0qOO3h90pT+XcIsFk3knzWH61YaEVc58MFXoNSdyb1CR44IlKYK9ksT\nf/d/XZE+mtTCz/b5eSOAiaGwM8F66pG+wfLguj9aqn18vIMB8bTUEDY9mCP4\nPyfu0nJQj7mdFnX1IJqb+aE9j8NnDGbyop2sTnC2/L45trOhRidYGkb71l1r\nd0y0CsLvqOZ+HQWnfAnmBwP2doVbeDlJSyK2mD4D4mystTmE6m54PlxZ7pzi\nfbH0FboujG6w18KL0hByQSbrZkt0T8LFbw0x64XwitlRvQhnaIwTNxLkxQ3h\n8aohtzOQ2c3L1Mk5u7udWGXY9/RyOm9+bF5/9sg+cbhPB+zfqcm2Gmb9MldR\n+q3v\r\n=LFAF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEz0CoKeL8MYFbKpvSl4U7FPi9v0PofWSl2Afwk27a5sAiAMT4+wXp69aCYq5wVXsCpocazxKzEojlsobkac9IABuQ=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4138326_1600356488181_0.508524795139927"},"_hasShrinkwrap":false},"4.0.4138613":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4138613","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.6.2","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4138613","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-5J8EetXOH3y+YeK7TcRLU6kMpVg/l679eOv/UOG3FDXFx15kSwhUHsDkB09gLlnZR7JgLJjbSIBihZyNCPodJg==","shasum":"0ea91c7dcd9c833a7c50a9de844cc79b3571b2e9","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4138613.tgz","fileCount":184,"unpackedSize":4239319,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfY4rwCRA9TVsSAnZWagAAT9YP/3VabgPTa0Kt7PvJlDow\nxvyPVayitcsOgu48xzbnjLd7fwgGlrcqfsXghQ7ZbBONpwInkoxTYDpUR83G\nlC5TmYvmxmWBsq7SpcFYigXLggdy3Ro0z4dx3nTwOM6Zu9xpxEHiCYLp3RtJ\ntsF2RemUEf2DJJsfGPG/0+8iJr2I8Q5ljo3UKj9jlL3g0NbUvpqLT6SRDn9H\n+HGpwh4rizP8/6AHwIHWyyz2WHRAYeRo3bYfjHzB1Q/PZT8iayD/tEStGBAm\ne3lbg3+Zgc0oxARV4WWGhXmqs1HBz39Njjylf6bTIY1SMHnPm5BHiCz/396y\nrJ8TVDsrH7yppJVvLLqPSsCmO8eziCvUecxDFAgBf8mDx5I8SJi+2jJWGGHK\nc/1UVw7CVuVjRK+zBAb2o6Lt7qShpZt1+il0xBHWp+4ZRB2C2TlgHbBfLLWL\ngNiVFLv637zo5DYgJwBEl3BkoxCwzr1MNWQSZDDP7+vrSmSTiYLvbw5k0/F8\nfaJ4culNtpUhMKThIjaZTatLNnVJVRo0dSseXwzGTErewvLhp+uGv0gZTNaP\nutzBtg46aW3BLFNYHjSSYZmw9juwB0dMdemV6E7m3ZA9Z5m9ou+e9aaJLTvM\nQ2UikHpQBb6JNNccqW298eZ86C8NLXzUEExNHs3SxR380w2IqtjR9i8JuTXJ\n0U/A\r\n=hXlU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFkSb8vDZnmHz9sVDYvsZ+9yTZQEtzBEWjmfMaQjPJOLAiAIoEsE+b3F+eM4b7p4O9pU4P8DVUwUgoXwIt4lzXD/uA=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4138613_1600359151737_0.7573408486044713"},"_hasShrinkwrap":false},"4.0.4138732":{"name":"@metrichor/epi2me-api","version":"4.0.4138732","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register ","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"bd624c9dd3c493912f3e248d033265a48a5157d6","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4138732","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-nX3EZHlqZiA44jmBKeH/LaZJgU5+ZNPfPAwa2zE+3XjRYQ+sJQHsY2FA2k0X7C5/G1VVDNsgs2pz7uqR1bfKFg==","shasum":"9913eedcadd17cbea360d9baab2ddc3772fc3d33","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4138732.tgz","fileCount":350,"unpackedSize":1105569,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfY5FWCRA9TVsSAnZWagAAUDkP/2LHC9e+CuKyVI2EtDGp\nrMJDL0mW7iCb2ggcPi5IJ6djOXDHB+SzrZRaJZmg6ygZ+3TTBeHAl34IL5oK\nRcxqWnp+Vxqxra9R2ZNK1vW41WUZ0lFoXqfjCMKxYVbo8RmJMME4zUiRODOQ\ntpoGgAgx6koz+QMgUTfZkcg5rCxRTpt/7g9Om5/hjUODxQQwAxGivwDEE+tI\ng18KlbqXTXAuS6tB8/S52sNwAQvsa5/ukJNhOYp4QeZbp3M0aDFIN9C6XbNj\nPmpx8FJ4p4uRvAy4pchLL8/zPX1DNFS+oXHMBqgT3gxCrlEGAyVvOm3b25mM\nmLKualFi8MTpINI8N6AZNzheq/SwAe47VwY22wOJafgSS3gk+6ZXw9CvdlUK\nog9Q9MejF7fCfwOD0XR/zjLovxSGMAfnoKDCBqv/N1dBAXvOYKqJpgEXrusZ\nuqcg9wwgTm86kOXyeBktz3B2lI0m1R5cYya4FaDT5ghioyb2lLrMGhIVMhhl\nv4do+JIxjVbUVxsYifQb1s0yDSikMuan3ZE3KpT1KRwMgwPzvURzBjERxniu\nqnFXAUQSAkI7ThcLIh1MtzJsMXii4f/tIx8pKQxYe6AnA9vYp89UhTTmhOEX\n8ZGIKjjsepBp69JV61zooRyenKo/OikdZqofRqrw3X8iHjfr2krgXNz1m89Q\nqZTy\r\n=s5z1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDZE9fiAMEPhUqwHwK5ookZoK5/LC+FmoYJSKcB94Om0gIhAI4LZ6ZKm7ACvFCWv1AEs3KvqXyMmJCk4RsNwTo6odZq"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4138732_1600360789833_0.6277294022122077"},"_hasShrinkwrap":false},"4.0.4139980":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4139980","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4139980","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-aysq0VumyxVH7p6b/2k4E2MbUDJQ1EFUxpuYUvdmoU8o9GkTDPnFfAvDvzQs91PmXY6oHPI4DHxgGaMejql5mw==","shasum":"08f2d0c5a3e43cc68bc0e579f10f11300b30894c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4139980.tgz","fileCount":184,"unpackedSize":4239922,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZEpDCRA9TVsSAnZWagAANfIP/14bAFCyS0OzFkgiplg1\n/xRkuavSZeXIbuwyrilu76X8Aq40F5foHDPw/ZXUU3IL0+/2CErb0brOT5Rp\nKYczVtboC8exacKjct378OFLVozbHFfriFaCQzejB0Sh+aX8IX0+cow4bm9F\nBEOcyH+ZIWOUYH3JxogGiS9pcJBYG0VUFCHTYxNIj82+0SmzqeAu5rFcIewx\nVEsYzgZPTSdTJbQmMC7Hw0gZJLLQwtmtomrRtGFs6bZa3tB1LitSjwG5A6bu\n9fnoIE7KsKxW+1U8EZfFhbjxjDallT8Q0N60dwOR7AYfddY0F9YE1g/ZGCua\ngBxAX4AA61uu0qNmpMMjsOAscoAeHY7zGXKr69XdiOs1adlhL6SYuYule/X9\nix0l3TdDyxpzFZC+XB9zOIBoDMUxPCAbFQOApDzNeKhsmZ9g/XyjkJu+NlWJ\nWlB7NlfozWDh/2ZpknG1I7lY2GABkDVIcgbJsIGvXGejA6VzceGSh5rPOCXP\nrxQFs0DkWGg+hs+lA/yscTnMpgD4haNxXaaXPC+cRuWGkVMwaCLuULnzyHcz\nCkPeWpPgWLGn5n5ySsrnSp9PW/VWt6SSsaxvG8zSpmI8JHWj2q8IvzJs7/oN\nncqkgN5VavsrxTu4WzCCtcwtgtdyct/iCvfkLveYR2SI8zwc1PczQmgkOm0p\nzI9b\r\n=Ff9C\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG6UC3S9+jwtxVhhN+uOOoke4R1/76L1vexR1chz4mHqAiAj21EM8iW5EOtnYCc5G0m0n7pjHRpYvJs5BHrTr/xglg=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4139980_1600408130962_0.6982535733632862"},"_hasShrinkwrap":false},"4.0.4144912":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4144912","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4144912","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-lOz+zi0eiwg4LUrpLWOyp4o41/og9TPeblWMR1oEAEMv5b+yvKEIl37r49/F5QXogQ4tpsBUzArBiq3c9bgL1Q==","shasum":"eeffd0a6958523ee046700d11733be2e2037258b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4144912.tgz","fileCount":185,"unpackedSize":4239986,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZN/JCRA9TVsSAnZWagAAoiMP/Rmqfw7KqnfPs5ODT4Hp\nKFzU1N5hO/7lo0eLL/5AQYn2bQ3qtJKn1af5UIf2tZ38kmFCUzT0NB94U53e\nGQoirm0sh6ATw/zDhY+1+RlIBxfMhRIKZk1xvrmM78YKjpTwGJL652sA0NAu\nbawwBfepVWpMTFCslgRRJoteO5UJTY4m1x2cOBzViRv1f318t7NXpgG/wHEj\ndM002w8wmsBzSB0gX48R4TBgV7/laMJ8GnDWlxRrtSRQPGaT2azTUMaGUBm/\njnvrT96xj9NZKFODSSS7ey/JubqOgikW410B4UpJFgVq7UvhLxNQQdAQyYJ7\ngHIPuk25kRJ5XX+MhnClnsayWAG826C9gPPZBTmD2Tt5pyRavY3pqnL/H8W1\nBN/E8HEE8Mwa3bVIAXvGUlznLAjMRpT+ycEan3rwyU190DnuUnE6poDXUg0u\nOaDZGAJxVhX5jD0aePBk45KpK84D1Y9KWGFnhdqZYivfRW4G0ZsrEoLr9R2K\n5KNuehsA202on0YXgvQKbKYBXiJjOnxz7brzCYp4dRFK3kpPVh9J7f0c5SPr\ncdoEHlYlqFPYPuNF+FcbY+jVDg0OzB5OIrUt2m9GLhbupfj5+CLkwNVjrTv6\nJR5A/RHMIkFdWow9XdM0IzJu3/L7Q+nrVLJ/397Hdqo39kSmSygSQCLdx0ru\nnVFb\r\n=IF1O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEy88/aqkRB8/6USAzI14dVAolFDMpTha2yGGAc9Mh6JAiEA1KiXhEh1mvIEC6uNiskh3CxDTfHnNkrDhDE2l8fueio="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4144912_1600446409321_0.3155751548583099"},"_hasShrinkwrap":false},"4.0.4144909":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4144909","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4144909","_nodeVersion":"14.5.0","_npmVersion":"6.14.5","dist":{"integrity":"sha512-XLX9p6dQ+A9kKQjvAGbdgBOemsvS+pWTyFapQ3/uG5TglSFcSNYa0zEv+xvKfK8Fc9XIS+mVAxgBTe9rXBEyzQ==","shasum":"c79736306e42fe7681283879c465db90fbe6238e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4144909.tgz","fileCount":185,"unpackedSize":4239986,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZN/pCRA9TVsSAnZWagAAu48QAIPdlxRORjZTfbhofYrj\nZCSOt3RSsqdH63j2jlvzQ6UIVNgLab8H6bSV7CZojV0VQ0bRMm30w6KtZwhv\nOosCmdazW9Nz6XsTEfBf/DDMaYudmwASeArwv7IjvSZFn4sBH/HfpWltqi1b\n1IJt/3/d2+mm50EhIW7D4RvmEg+J72G6WP6sg4zYngtsuvwImhurP2DZK+k5\nlpKC06Iv0A6weWUg6nROGNF6bYV5pu254aDpAprX6UdJ0y+GDgjyCypIXTMs\noQXHvZr3BaOz+7Rgx/vwRC1EYMhZUUj9V2sFFzo4qQyXZEtAJJRunBf7HyAp\noMIAYXm//Es9+ER4R74xQOVoVrQLuoQfg0wXbLVZqqDonK3d1hSxMjFlWHAV\nthjNk4ikP/MGPMM6MusYpfJXqQw71349lTkfCp7pvYCPmEVaL8NHBocxbcZa\nBJeNIrJzpEwYnPhLgMjvOjQMF4ZvvXG+aCQqGHoJEudHO+gONoX9UhgTqczU\nXI4jnhURUPmmNSmRhhRLjzQz+hIXfiGlk4WvW8XrebG6VxOW7abPaD8ejxr5\nH5H4hYrnrq/dDbmYnSejcuoakoT8jDIIjrlDNtF/1UXaRo7csYZ4kg92Ofej\nEiDHDktsMRhLV2bCy02XDKskzmjqRnn7cRSw5ZF2Dt3ObHq5YxHdzMg/pQ9v\n2K6t\r\n=NRnW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICXoEdlnI7ftK/aTom9+eAGYK8gV9jg3xZQZKqKtpHNHAiAZ2hd0AghYEX/5rZQK6hNVrN1GqWDvNrLjWemmDZB48g=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4144909_1600446440963_0.021715896559300063"},"_hasShrinkwrap":false},"4.0.4144922":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4144922","main":"index.js","module":"index.esm.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4144922","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-zI6UNHuWegZSpqNiAXliTlk4mb/ChycHZS5GuZ7xzzmJacA44hvPP6X+ETC8Ase7CA4ccEtXhYzcBgIedyVgFQ==","shasum":"a7704615b6470e1675d7581a7ed417491949a537","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4144922.tgz","fileCount":185,"unpackedSize":4239986,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZOEpCRA9TVsSAnZWagAAes4QAIc7EZKtJal6y0rZg0W6\nDhYEMmFwRxRVFQlSD8Nos/Mm522clC1/jivdGOaXTOHsUB6vBpIxkAcDhxTr\nt5AtCtyyuPVQ19wzq1NGM2Q8/Y35MIWcVs8IPsS7HNMOX2nxTVR1BYQW44mN\nGn2/QdffrauBqKgD1KFukC2uWfQ0geolYD4oRUIpFDiWiYVwRWcEcTh3ouGC\nRsLSSVtcYsfL5VVx+wZuBEj9L2K21LMQ1S0UZNvqbaywZG90dEPuMAaU6yH5\nUmNi3KcaBkkDwfI5kLPO26RBnLwcm49B4yWaDEPxJX/cqMiABAjteiyGJByw\nD1KQSCcNL+k8SeGweIh3L75krbADTO6w9MLUMQsONR4HWSbBEDf57tGPLv4q\nWOwT2GGunIaLPDfXDU2By5tbI4V0dvpEstkpm/ILbIU17VRfxxG3BgYAag5o\ny3LbLgo55GS/Agfuhwv8a/zQZY2MjP7XGspWt8Nv1jhbBk6BTBEtISlGyhhk\n53B7yJn9JDAecJ2vxFxyNHXbGT3KuyXlnmW1L1k35l5mxKZaatfj/zTv7EuZ\n1RbUalEh/o0ejqeJuonde4lsip2xnjSnfNj7b9KHi+ESZ9lBYUtN1NmQ7BRZ\nNAH3e9QGyjy2oZP1++xj8tdwgvK7h58FaigW1EAvnWE+vRsw0+/oYYb9CKah\nX5/4\r\n=a0HQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCoMpGYTyLINfCyoA80i7uP7FAtTzN4TceSeLGSVixsjwIgbg4tDFvEis8deJOrpq113Okd/UliP9MdiMj2ChSxnac="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4144922_1600446760932_0.5696019760899809"},"_hasShrinkwrap":false},"4.0.4149450":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4149450","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4149450","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-Gp4wS5Lx7QfemXMqCFcDYyt5nVnxmwVZEr4tbD/VtHoDzPVHMhB1UeqQTx2wG2BD2DeeIKYxqusiK4mfYc0QEQ==","shasum":"376b08374e2d26077dcdb258bb535b187d842c27","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4149450.tgz","fileCount":181,"unpackedSize":2444212,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfaGz1CRA9TVsSAnZWagAAvVoP/1ag2y/Wlc++16I6njor\n3cl8U15Mkd/xt748kKd1oUrttg91BwtlOl+PVcWrzrAYQTMS96WR0GyvNJ7p\n9dqtCyFPY4w2JG3MecQltx3wKucVrzWdPLE9U4mnhFqQZrHH/3WQo4DIeBZ1\nnC0ZSBmjBIbq6axvExle64l9mkLZGWbwTNFNGUENN9JJwl4/ezsqvlQ0jiz6\nsKJWSJXZllTiXgWfvNZEAobYd2OaVo8wkH8+ifNvdE0ph1oSOXuaR18tayC3\n1QoJ/Mw1/vCWVtKTKyzHh8jYyoRv1aLLfIm6DzGVneVi5sLBZUenUWtUvmba\nLfSq1RXxE79Y2pCitOth3OIKQOr8zgBct639wlqxiLME/s7wn2FclX27Tf2e\nvS1BciMSrpJHyXMm2o0rVcd0aQjTufABtRVQWp32DZQWHPU69jZ5j7BbDvIZ\nmGtley5IfaKiyS2dchf2RvMv29TIAB/11fKOEpuE2aTMDJiEY3mi2xApVlbx\nVEAlLabrKDOh0rArtKlMXbgMsV6TuhsPjPgcmrUHSAd4tw1rdbWpCV/qjzgM\nSahnpLHz7sg7kqzvfDxkzfaln7Lu7F4FTzjZgrVMzZLlv5YXyyGdhyBNrhVH\nf/vniE9gXSCZnw7LOLrVf9z6UqPaRp0PRVJzcrXRyJOr7iEGK2to8zcKsbUx\nExmc\r\n=bKWz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD9xOmf8Sl8uG7HX0yLXVvNqZo72l0Jv/QURZv07lnvrAIgUo7iBXaA8UXsfoMOAuo61aa/hynfk96gFQ77/3SqWEM="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4149450_1600679156974_0.8432905819876062"},"_hasShrinkwrap":false},"4.0.4152828":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4152828","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4152828","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-NuSUksWyy27BX7iUhWUJsZgKCw94tW6qOYpNHs61Fw8rb3TPSdVX8J0NdCb4WGn0Imih4z0LNBgH6aRLc9ONCA==","shasum":"7502e149104a0cfacc7f25015b4ef7d4d89c33e4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4152828.tgz","fileCount":181,"unpackedSize":2443945,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfaMfrCRA9TVsSAnZWagAAwQwP/R0XLsF3dQXffIJEM0c+\np12oL9cieEKximTyd79S0iAfuZ8teowob8/bxSVvYXnFXfmHsYfW257dFZZl\njeGHm6guV+zQMLzSI724/4E1MRC0I0FIM0X0ACWFdDNt420ppUPe/ycAktnM\nbJHaUOxy+CBrQ56bFHTW8b03CdVfvH9399murBsZG9g5JMvEMKPnpv+0wCB9\nQ8qy8W5/trRBXSmtQfcmmvGz91Y+ps4OVeZ8ztx7xDWhvxHVeEOZAI8HbrV4\nlSfXJYRdMZlDTknZJ3JQsyufLKNdmHTwohqN5omDDGlH8jY71SmmdrCI1fS2\nXRDo3d3q23wWhM+kapAcbMEzzinrlU5DTxCvNWiVxQm7lD/U+PEMSiOd1xXP\ndw9F0tNGiyx15ZQ3RCY7qWUDPQjsnG4XgFMpf+k/vbgWXnbvuavEDsa3O/NQ\nkGn2EvMedw93U9YBW8T6i5xq5AX2wzkyT5LKs7Bh0rcf3vbQLFR96/dhafc6\nNEJj5wGidTjrXPaKuYYqfFis3LbwgWytZ36z0LGrIDdzs9MWvdlW+BoF9vOW\no41V8VjkXRtiGSmvcXBxm2z7Mh/rHQ7zd1ot7gTePSQF1nZ1sAIdcjyZcNxc\njihljRChWHfR/PY+w2TrL36jDceotHhdlV+xnUhgbEhWLR4Oqg6dZwIqrJ60\n16qD\r\n=zDdT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCoS8JIbB6TsRgQxn+wTAZk5arMQyusrhwr63VYlhexogIgdLx/33o/BFzxbFwdcW1vE2WqhoKPaNp4drZMPgrEEj0="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4152828_1600702442553_0.7712294299590747"},"_hasShrinkwrap":false},"4.0.4153188":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4153188","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4153188","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-UOXItBROnUq95dxs7GB08PcF6f2JIZj/VpSOPSu8Gka8nNFjGYjL3yeOS1+4pnQIeEPUYQ7f8mUp4yF4OQFP+A==","shasum":"6edc9b42e2b60f3a7d5d762759e11d4f82e7373f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4153188.tgz","fileCount":181,"unpackedSize":2443945,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfaNauCRA9TVsSAnZWagAA6BMQAImfkdfyndFmyF9PchcC\nux1+LsSBlL9Utujl3+0Rodef47gk2y8/Oc4lQt0/qA+VmietEGtxH4VgXCgf\nS+KuRXs381/KJxavCpxzMPWu+gST6aB/hzR3E4tEdW5vM0KL7y/PfmZ80djn\n33ISEkW+ZgFIMbHZVcJHvLxfe94bYky7B/iSizZ4iIQXy9LMVK1pZR+RCOZ+\ncDL91zrxM4svdoVZFi5BDKbRvAmhfPbJz+x1V6TA3tv8yiS8417P/yGoADvP\n8cmIkLA3PBf+PQVm2wRmK27Qy+oYTBUlvR9tyEd4Tu2XZAEGtM8lv/9UlyFb\nHJGfCc0TyP0OJBqLOsdr+JF6qhMq9kPJp5Cc/ptDZu1ybMmzXbsRO2Dc/9++\nJyAjrHxeEceWYzDB7qoMlHwdgwEvpcTB//2xp41Ou3/dla+keyO7mVanoY8v\n+lrvWrJXYv/rZ4vyh3vzNW/HQH0ky4QTuByXXk3bgloCYuPOIGufunnlEdvs\nrJqvDjyf+psZTNsxt7eH8duVt/rBOvoIYOgMbDjhE97ZbP3EbdxADwmtQu7C\nQlIaNn9+gsLfuqboJ3vJ7GZuwB5Sq6lEa1NUct8PEftiLNCYN9T8AZdj05/e\njz/p3r7l3+h8NGgJDJilQkOQ1jH/5fVWANWVaH1+96MBboEsGDqJLe4eOGwH\n663P\r\n=2lgZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCF20pTtt9Gpj3HJFkB8KfhwF/jWF8jvKSoIe+VwfTdJgIhAL6mLvTnJrzldvpzfS0LKwNuRviYDjlY/6vl339ol6zD"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4153188_1600706221765_0.5575067773426403"},"_hasShrinkwrap":false},"4.0.4153687":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4153687","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4153687","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-uti5V2NUa58WWx1oIUcfJ1Awrod5ssSjmo5wvSLOhKUKIC9elTLPuBNTItTw9AEJ29uPtgGDHffswrpY5O2l8Q==","shasum":"5139d9b9a7ad0a52af1a0ed27cd5ca0ac0b308ab","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4153687.tgz","fileCount":181,"unpackedSize":2443945,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfaR9+CRA9TVsSAnZWagAA/osP/3oVN7teK2Rf4s46PTwQ\nLIwaZhJ6fA5HDENPhkLZ5XxBNRCJuiTWzb2bqDaWde5/YN9Oo6ZdyFq4QbWc\nthq7uAvCnkuqMJVQZE3WgiUbOxgqLdCPLnPyowbeGTboRxIDrxljm/WHC1o7\nnTtN3WP5ktC+qw9yeZnR4B3DNhaBQjUQGWE+dxCTd8uRBNVcCNszxqLb2NJh\nrYi/OU3BU1rDPP9S9IzWJfWeDe7RqqAdJGmOSma2N3MjFMXVP1PnbN4j1diB\nvu0nfpe7t4qvC1XGaUUzstjbk2KQRSfOvR1RDbiM5gMiMtJxI+xSd0RdSOFa\ncwlmNiUkO5l9IWBgma6w2iaAsh0XX5T0WIspzjYazJZaumOx5ZR10e9xRvjC\nRBC7zz8sQIU2YtKw9gJDze7Zb5ftklLUcz1Kl+lChV+V/YXh9nGBbquxngo6\nAFRLipdzjIbyZhQ8Frd3U01asYKly+iW6zlcprO0R3BpLmiXiYf9VEu6eWr1\nxy5BMMFH2bbSr5VHctDd1Ajd3CgrdPSSa6X5v0HGAFr4d59tE/uEWNSFsdb+\nspbkCG6S9Spqd4u8cA59Kd1pdDWFnfuVzJBYr5oCP+iyLdPvd86UDCQPGt5K\ndRvL8HSdT9Psfou4i3Am41sUXK3s3Ei/kcryBsH8gIEPKP7Ce+cSYt/Vf+pI\njRrH\r\n=ffcB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDmlo20y0sma4sfyeqvhepYMS1gXpz1F6ibJ0AI/juWcgIgchcXu7KwkbMx+zI/YcpYFaVD2jkuLG90PfmJ8GDazOw="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4153687_1600724861436_0.16194490682204132"},"_hasShrinkwrap":false},"4.0.4153945":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4153945","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4153945","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-J7KjrXOlLWS3v7TJ1NBoDoi2tS/SlyPeISq3+wbqCY1mZxOpf+XGYxQMEIOX0FDtKsdQib2u+mf5Q3u38WUhBg==","shasum":"fd5ef7cdbf5217821a1cc3ce1f8fb77d09f0cd8a","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4153945.tgz","fileCount":181,"unpackedSize":2443945,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfaSEICRA9TVsSAnZWagAAgcsP/je3o75XOiZNLz0n+/t4\nHHMEEvb0j3ARUF+7H9hCWWJ/RpQmU75ZGLHt6+xU9fhSTFEImRlG0av76UYq\njzPWp7TbJ4qQTgGqPA5Xga2dLbK7ZpG/BG6jE232yx4nNntFuJzK3Y2uQ/1m\nuYBukkh6seU75TS0T9BzWNVgV30a+U3v421yYDthI8HHap4XwbJtPj+xcymv\nqNkq0iR/J3pyGY4ClI9BPkMXEfnkRS01+py2MbCZ2KBAx5bPj720c3/gTpDA\nN09IL+BMRLgGuKEn+J7AR6d0XhSeRlXuJfiKmsQHngQOJeCSj/usiTCXOEAK\nm8XFeQ6POeKuljTHyyPIYaCFhkGh6gwEchq9XTdwNT1IXCIdAZEvFl75vu7i\nrukwM20NN/5JAln1Pe4TOQ17eOZkEltWvmryYaL+FN2sSYKJxquSHb0cQc1U\ne9rPvnqToJjB41Fs0H5nfF26wP63eZTr8HkJhJMRASyq1jX/aNrGg3KomijO\n50VDJdzc7yAgDnmTHA4sCZ9iFoG7BIbzwKGaSC/VvfIlu0riVN3l1fNHgaiK\nJYoaoNw/oi5fJzUCtYdaxZ34uH7l0HnkIwNuWANoMaVltoO7GgWRRrXCmMKN\nixz8YlwjNX90wM4XuYn+2oH23zKsSJLbMA9OX3haXqnwnMgapvVR8Dcp6Frj\nVSOK\r\n=dCu4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG6+5vag975iojt18Is9Y38A1Y88PcAVPlrBkGmI4xxQAiALFfM/Fo2tgWLzs/MgbbDTKwe03qszgP31SHazck+WeA=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4153945_1600725255891_0.1785544397813954"},"_hasShrinkwrap":false},"4.0.4167526":{"name":"@metrichor/epi2me-api","version":"4.0.4167526","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","types":"dist/src/index.d.ts","main":"./dist/index.js","dependencies":{"@apollo/client":"^3.1.3","@improbable-eng/grpc-web":"^0.13.0","@improbable-eng/grpc-web-node-http-transport":"^0.13.0","@lifeomic/axios-fetch":"^1.4.2","@types/lifeomic__axios-fetch":"^1.4.0","@types/socket.io-client":"^1.4.32","aws-sdk":"^2.610.0","axios":"^0.19.2","core-js":"^3.6.4","cross-fetch":"^3.0.5","fdir":"^3.4.3","fs-extra":"^8.1.0","google-protobuf":"^3.13.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","grpc":"^1.24.3","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","save":"^2.4.0","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"devDependencies":{"@rollup/plugin-commonjs":"^14.0.0","@types/bunyan":"^1.8.6","@types/fs-extra":"^8.1.0","@types/google-protobuf":"^3.7.3","@types/lodash":"^4.14.149","@types/mocha":"^7.0.2","@types/node":"^14.0.24","@types/rollup":"^0.54.0","@types/rollup-plugin-json":"^3.0.2","@types/tunnel":"0.0.1","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","bunyan":"^1.8.12","eslint":"^7.6.0","eslint-config-prettier":"^6.11.0","eslint-plugin-prettier":"^3.1.4","grpc-tools":"^1.9.1","husky":"^4.2.1","lint-staged":"^10.0.4","mocha":"^8.1.1","mock-fs":"^4.11.0","nyc":"^15.0.0","prettier":"^2.0.5","rollup":"^2.22.1","rollup-plugin-analyzer":"^3.2.1","rollup-plugin-cpy":"^2.0.1","rollup-plugin-eslint":"^7.0.0","rollup-plugin-generate-package-json":"^3.1.3","rollup-plugin-json":"^4.0.0","rollup-plugin-license":"^2.2.0","rollup-plugin-terser":"^7.0.0","rollup-plugin-typescript2":"^0.27.1","sinon":"^8.1.1","tmp":"^0.1.0","ts-node":"^8.6.2","ts-protoc-gen":"^0.12.0","tslib":"^2.0.0","typescript":"^3.9.7","xunit-file":"*"},"browserslist":[">0.2%","not dead","not ie <= 11","not op_mini all"],"lint-staged":{"*.{ts,tsx,js,jsx}":["npm run lint:fix","git add --force"],"*.{json,md,graphql}":["prettier --write","git add --force"]},"scripts":{"build:version":"jq \".version=\\\"$(jq -r .version package.json | cut -d . -f 1-2).${PATCH:-$(date +%-H%M)}\\\"\" < package.json > package.json.tmp && mv package.json.tmp package.json","lint:source":"eslint '*/**/*.{js,ts,tsx}' --ignore-path .eslintignore --ignore-pattern \"!**/.*\"","lint:quiet":"npm run lint:source -- --quiet","lint:warn":"npm run lint:source","lint:fix":"npm run lint:quiet -- --fix","lint":"npm run lint:quiet","deps":"npm ci","clean:dist":"rm -rf dist","clean:build":"rm -rf build && rm -rf dist/lib","clean":"npm run clean:build && npm run clean:dist","test":"mocha --recursive --require ts-node/register test/**/*.{js,ts}","test:single":"mocha --require ts-node/register test/**/*.{js,ts}","cover":"npm install && npm run lint && npx nyc --reporter=html --reporter=text mocha --recursive --require ts-node/register test","build":"npm ci && npm run build:dist","rollup:build":"npx rollup -c","rollup:watch":"npx rollup -cw","build:light":"npm run clean:dist && npm run build:protos && npm run rollup:build","build:dist":"npm run build:version && npm run build:light","ts:defs":"tsc --outDir dist --declarationDir dist/types --emitDeclarationOnly","build:protos":"rm -rf ./protos/* && ./build_protos.sh"},"gitHead":"842b31a04936e4bf303d989535a6079fa325b064","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4167526","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-wdrmLBQviMe4ItgoQZzkn0MliO8+O0Cl1lMW4prMTOLAsuFRJXE9RqhXfgzFuASfyrfR2I3M63hXNemw4HGzQQ==","shasum":"0183a4efafdba6cdec696714add9d931b5a85bdf","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4167526.tgz","fileCount":351,"unpackedSize":1105562,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfbFypCRA9TVsSAnZWagAA5uYP/1SUXIWoT5hps9TW4hMw\nGQ644Cp8N+xwSDo//OJWMHARckeTZEClF1dcAv7Mx4ZOSHg7i3FiT0p7qkn1\nETPcymRyHb3VykI5NmKARyd31pTEbPSdZwgo1wLk3tJNiP9WpHi/kQTixzsh\nv1CahI1BmqcKa438dzkVGLSdyxeChOGRBqcI+9/CsooeRTCBFBAs4OHr5zo9\nOMkNKg1SbrtjjQHUoheYDnJaOZ95nUlQvTcAyTtpC95K+D033QdXP+Z3WeEq\ng1n2rduWEdpQsKHhysuWGc80lxRDiRWFELu8K65wW04GuG6sjWbQxKJM2nYr\nwVKpUKOMugx9WCwhj4D6cLoEx5LsAftWHTva5h3szbHIa4H/8HdZEfD3/HFQ\nDW0FZ12X15ayEj46FVnGRbyIXQqAJILtf1MqcmxXYbYamMeWJvKOFSQV90rN\nrza3vLOBGLzArGF24ust4ntgipeN+gXYvcp/cFFGI1R75JxeTuojOYdcUyn2\nayDvpkTlm7/q4o5xz/HwYprZWOdBryuavlYzylAMSU9Ea+SDdj6wS9HOVxnu\ne6A3qZuC6IQ2sWx6/sS0v4GR+1O7zNzJQEf4x48ZGJ/PrPVJfYpS40QnGSzk\nKdAHmczZOm/9dqeVt+v6y1sPXChdByfifLzW8UXNIMMgh8hkl38kCzs8SL1s\nA7AQ\r\n=wLgU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICxtAOOdtHrbcFxISbw5iRgHgU5pFqR+tZd5tCxu/PPCAiEA//fNDdhXkXvt0xOcxIfO1j8gRRGshs6tr3cG3COFzIM="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4167526_1600937129195_0.08214250760235098"},"_hasShrinkwrap":false},"4.0.4167529":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4167529","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4167529","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-ALsTBy+JmIZZT8MtKH4UWrdfjv13GAlVx+5FJP5eje8RTWUvJcTQkVdxfPc8qAFTLlVZMUnwauKUjm0ps7GF5g==","shasum":"f62929b407eeee59f5e5c0a2cbcc66b642879e8e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4167529.tgz","fileCount":184,"unpackedSize":2444852,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfbF/0CRA9TVsSAnZWagAA6AUP/R22iYRLldM5vGl1Zvxe\nx31H1t3igl4Fu0LKIkq8wMnXWIGIiP1Q8hmoKntIkgPv8zcW0uE4HBaBijvV\nBC2E7JjdJPTSP9tqTizdRt2K/iLUsq/3bU6szochOWTm/DbcMNspj73xszR2\nttwb5R8c4v3MOqp+OTzlU7unYDljXzpoGjUauDBASS3T9o2YCNMTjCs6ZvIU\nB5Xx7yMGRkq3sBVzBJQyT9Z1lafDcvQXU/2e82ROuGK9mpJP5hDUuD5bzwuI\nKmbJmhAnGLTzolZ2bdeePJUGO5zSYsn5w3iET+MUA6jJ5fQSAGb+YcjecVk3\nSozS+7VwvYdDv3aNTLJ8GnaiaKE0NPMDQR2tKXIotAoVc5g7ePsi1GPheAQT\nYlGItVwFwPAnoA6ATG0+R2Qgf3c9V86eZS29aWBSIsG3F4TvHqvYB1qA9DNH\nYXCF84qIMe+6Knus5JRS495Tpw40LepiD1fNJ8LaiNk4fg3sQ5D8SQN8pUP/\nwcUsif/oL5qKO11d+ZnxV+k6nmThRD0JB7ZAgZhVOH5vWj7vnGBQe/36lV56\n3NTsvL/AxDwvOYLc/5qO4MHc+h/x0/NrkJCp0mvqdt0Zqzw8tpBR62Uxfhdi\njovEnc5JPpc9WwRl4BWdP0BWNKy26JSjpin7i7zaOL9go/m6wKd2kHQw1So3\nBltF\r\n=obDt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD1rRrxB7nNpJzQF9mJ0OzFiivewxspv01Do5MPB5z4jQIgMWJzWE+p+IQVwDLJB17GY/9vhLmMU8CnIFHu9TZhHCs="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4167529_1600937972259_0.2189825763110873"},"_hasShrinkwrap":false},"4.0.4167714":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4167714","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4167714","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-+l/xAbGWBESf7PNheldW/s4ITC6umEo9i+wz/dsgCvLDhzuQSWyXVB9w8mUyyZRdi+IUnKQztSbMlHZvFmz1Fg==","shasum":"5d02a89405015059316db2622204817ed0733189","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4167714.tgz","fileCount":184,"unpackedSize":2444852,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfbGHYCRA9TVsSAnZWagAANT0QAIas/gwiPU/++uFnSNop\nOfaSmq8qabc6DggsBNtAb6yqggfa83wxA3ZpffwhCW2/IIe6g71jjASJ5hGN\n2TYjxf3fK5ebU2vOcNV3pGs0/FPiXFR0qc8hnS/6R0d1bL76Vi4qGFfelGFd\nggJcEFtkwr5Oz2f+c89Yo80IcDwO75mJ5ic6qwibM5cuaMhSi1yLjG+PKje2\nC9WEHoP+2zYjV9zdMEyYDBaB4JhAcdoE7ULcgh6nCkjwlJw6Tt8i656G474p\nZpELbqBRsUK06aOf4w+wG/YLgR5Wx9S3+mWRrtwCJ6/NqhUk4yLTTUR3D3S3\nNC9mc19x9NmNqTwQ9DOh5GBJ9WGlQ6wI8IJwI3AjiZrEULz/LZtV1X5833zx\nOVUohDNEBzcrnssWEUsA9uX1qMjppEX8C3JlL7Pyxt5CQJLxlismqXY1hB7Z\n63rdrvEXXTfMEfRxUTojbrfYn0ZshCxsQHSvuOXRC3GEsy48umL3spa3H+qo\nYllKccxSiLc5LqX/TiNwxHNMmQvVoogvzFIclh7N8P1Q8lJVEDaRKhpzSJ4p\nvMb0wRRfzBXpECxJ6Oj5Q1fvgIzBd5Xgf4byAT1uv/C8fS7FJ3+5A5sz7XzM\n+lKu1P+LNbpAw/3cDlHqjfOZKLnRCLsJfNmws57b5+k9Y1fHrrCmZhVsFIUh\nG5EG\r\n=lYQZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG8EPuLbbhPYR5pZLjC/aKj2tjCkTXLU0j/Pk0kd/bqnAiEA/L8d8dQ07wUt8U9i24vX5gLUe3qHyzks8g0VdSuyzGA="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4167714_1600938456455_0.26774384550711394"},"_hasShrinkwrap":false},"4.0.4177170":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4177170","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4177170","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-1v4+4H4SOQY3pRZf2AgIPJL3cCw66oKQgfFS4Lt/DKXJb3m2DEySP2GxINA6D2x+7gt/4p6Ykgg+lS8pnaWmrg==","shasum":"0f5c277e09eb25c59bfcdee19806981c76f8a82a","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4177170.tgz","fileCount":184,"unpackedSize":2445149,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfbfw0CRA9TVsSAnZWagAAwF0P/3j/yP2ezjBflWl06RxV\nIOk8VFCYnUaKnPDvlGZlFDHvEDH/bR7FJ3IfqO+Uhv30DaIjS+g8z1O6s5UJ\nRMRyEU/4C9MD41gRh96JSDMLgo3/r2LNFPGI/7A6spqeMI2XEo2hOfaEuudp\nGFypNk34ojZLXKdNBqUdO7bSPaWfD70VUEtpyGQ1Kj6spsB3fPJuV65fc2Wz\nPi8piqcYATvLR7beS4gTFzNG8dVZmziMd8JoiGC/PM31LrsA5PqjmV6x0Wv/\npn2K/OBs4jgYgo5jDHUtT319TbXPL3W21fw5B71WfKof9fRbS/6wnS8tRgfL\nkLxKagXYYtT+KKn750Mrxl0NGwAyDybqXQWVXAMt6YKry2tz9ny7gm5eHkby\nSRozUhn4q0NzictsWpnFH1dcrPlm9COigs2JrvgZV1JyGP+pP35JTJgdQze1\nzb7ikhQL7RsWiNWfffwuRIcYBM2CCF+M8ZYYddK8zRgN88e5i/ZNZT14c46Y\n5CN/GwxiK38bUJ5F3rmsM/4eTneeC1ps1xc072JV1syKbR8r688MvqE/ah2R\nAoNIpvmn6TbgaPy1q+gxCWRniC14I5gZNibIYOlz+DUiq5nBwwRx6Dixu5M5\n4vFcMzig4/5aV1slNnpYucLc+n7Nn4XXcyfFDp4jh/nTcRZvJB38O/mh7z/Q\n47ow\r\n=bhcV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHyrgZbwEjoeuJ3J5xSngjWIlLEyl7vJqWqYBGAN5hKgAiAW3CWhUZpRFwrIsRaHyHCydyP8T4sthDCldZeBJwoGKA=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4177170_1601043507802_0.6325746925220108"},"_hasShrinkwrap":false},"4.0.4177343":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4177343","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4177343","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-mSFxsTkrUSIBbfOksjD6ltKAguA+9ISMH27rdvJUkjZB0+SvVgtms6LC282rwrpDz8/s9iXH0vkGcGfqrV1nGA==","shasum":"02d09f8ba65121d789df69d642846c885690f53a","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4177343.tgz","fileCount":184,"unpackedSize":2445149,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfbgGSCRA9TVsSAnZWagAAZRcP/3jPxR5GhubLEePPNMMs\nN5zUIkEyj0CJ1KVNQYxcSjjBVxR+PQyp9d3DZSf0txxcMMuvi36Oqog1CUkE\nOtIO3ukawUJpPzr7Q7I1hfj4K9LClnlHc7Es5a1MU0ufIo8wKRTvTjQIAy5N\nzdTFf9nsZJxet7nQnyBjRaf9yqsZonoNpgc/5UR4KduoymGPyWzMGILcurBd\nwqnHkW+gbvifvbyAzlEHDF1b6CXbWGNPissFD5mlmWT9wj98SplL++ugFVQj\n37B7NrzVv6Vbx8D/N+SvzQmteH6QLk4CKlD3eE+DaDX2hvHCDk4j1a6rcSli\nEFIxzaH+OdWnzHqcdUUcUifDxGNTeWdViC3lM5phdJ+vQmlPDMgXqXBPEglt\nKf+y/CMALM4KRc3cwWjQpDLNIkZFvKnnezsGxWS654A8iV0me8lY/iLcLpaG\nFnIQ3DqxjW3ba4adoLCu1WqSOaI6c3VGELE/kdmAsu1NCR5EXziXXf8FUPfC\nRp2f/Wz08bqXHEut6nC+FtSumeERQq01TdVVutDCVRwU9vd+ve7hy7NuTyBu\nmh9tHsYskUCxu74bhDv7xfsQXUf63mNt8UHmzXa7DG79Yro56P4iPIGRtFso\n7hhcBaN9ojoHyeT4clc2+XIqtcoGOi+57IobvuI5nyhXMLmu+tR6ewVcHqIo\nXdNs\r\n=c1rv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC5dvuhe3r7owdSbLXgMlcvPDdTduenB/yjiBGnN3xMtgIgc/G9yRc+8WnXj7KmtZGwnnTyF+42SX7E0SKUtOXOwjg="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4177343_1601044881950_0.18869902672128336"},"_hasShrinkwrap":false},"4.0.4186216":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4186216","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4186216","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-VJZJcCSjU2rzyAvrQQNuoa8aaU8zViAbKZsVebId7i8w/6M/EadfA0+NOrzcCtAX+a4UPITM5Ds/YBAi4cx5jg==","shasum":"6c461455e3f7102a4c33d7302b3a4ef47641f349","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4186216.tgz","fileCount":184,"unpackedSize":2445149,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfciceCRA9TVsSAnZWagAAvEgP/2JLjLr43Q8H/w70sw9b\nnCstHNW2JdxUfUA6zkOIU+yS3QPBUd81qK6wgGlT7hKjdFSdvnyUXPleKgjW\n7fU9uMy6ze9BGpvGyCBzBixRuL8CVwyhevD8FwCmyNZB6HZRL8vf2B5pXsrC\nLZ0fJoCkKO978r4nMoWj4MI4MoZC7mIBUl+LcgSyKSkveoxWdw83zgDZGfge\nWqzT7N0mWf5gSBK3jznPFKCiQYiNKE7s6K76RFmHhYOc6vvFCKtJ1PRw/xgR\nTf3d5T4iMvoPvK5KemChv63i3vE+UZ/eeqcWlIRkCkvtjetw/jWCitUk8LLx\nOtF8El93RZIc1/Het4Hwyet/3ZIb8yqpLzR0AirXf0PArl8mK62FpUQo396o\ntTKVCO/gQdp3BrcmWEF+dK7WerfYLGFEgsEphUOZKOjONftHkOnO6Z4Zk2s7\nAJFVBK62heE/J1XO5mHK0zoVTh9ZVRR0Ty8rWOETc/TK9VhqZdUcQ08nqK0n\nmpZrLi+6nn195QG+yZxEydmWE9cF+0xxyqNAMq21/TfpHhWuSXZRcK8MwD8J\n7MSvCnleT+xT9Eoqr/Jk/ooUo3oITISb/n103IrdmghFAKmn3SSVGhsisH9u\nvw/npU2mvtHulh6KSKF83oRAAouCXKDKfsjNRWTtN0wL6omNjAkBtfQSGBoA\niNAb\r\n=A+19\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQChzLS0mbNIzJstBp++3HypIGVZKU5pF+8tRAcxK6dlIAIhALuXHzKNNsVSufxa50sVDTpfBmpMDEExxx5Ufq/WwEZm"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4186216_1601316637808_0.8529309705644637"},"_hasShrinkwrap":false},"4.0.4201189":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4201189","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4201189","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-wrieKIricgM5xWrkWd+SagrMV6AMUZfAZPBaTWzsvEbnZHgqK9fk2/oLkV1e9JwNnH3tG1u+1Oye6wYfQVAvcw==","shasum":"28e4ad2f5b364e35e25c91d4148c1f52988cdd46","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4201189.tgz","fileCount":184,"unpackedSize":2447611,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfduqGCRA9TVsSAnZWagAAv0wQAIaAisq0VSvIGrxy4DQ8\nU/3XUu9jnQSdfeyPj6dNY6rpeur/E3EBcDCylsJHr6Rjix2fiPUsM1sUxmJU\n+3KX1TLCbQ+Lioz+gRda7W88HeRvS6M1ogMfL84uc/gstkIZwz/lphFoMDVB\nlZ+A2N6FIi1fNOUFaTMsHJBzKySN/puF5O5QWIPXOmKCzyCUey8GsvpdzLJ9\nohST6DbVNOpZP6WJiNuS955KnC7XsilzkrPSfswiQORER/zfI1IjeZ9vxL9W\n1prBZw7g21kKBmVU58htE2x+1uUQ+i0+ksRwHp5G1M4qe2JcFjyv3IDroh3Z\nFNCxYPumjLiXbEYFSE6RJUh/GZvUivRvtTvxcbMJGJQpW35lwLYAURjxaI+d\nAa3s1BlbCFuPljmAKz9ux2DEai+SEfu+gmA8yRk5tsU72njxsbiqpGpKXnYW\nP4i77XIIDABoal042b9nOKlcJUJQVc9z3x/VyeKSGheTKxhzczhu/dTeHeu+\nMTe5TST/GdlF/Wr54mVOYOy/kHIuJ9uJUdNCjkEEtJVJmHeYSBNltRtSd1We\n4ad0y6G9mQXmKt+3V/0j1lULQ9PpD0Vmr/ne8/qti4BDFKpYr6i/Xu/R4GE3\n3xOTAfvtSgKGb/g+hh0kV8dGHzdeKnF/hMF9CbyBPnvlykFhU9+8lAAmLKtM\nnLe1\r\n=tPfs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDfZ04agE/+J8xZi8n+1EgJ5nma3TRfE5eNvJgiMeqrhwIgDUkHj/M9+X9ESy4qqTESCWB2Bih7Cf7zA/ZH00VJM+I="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4201189_1601628805394_0.4224077051654158"},"_hasShrinkwrap":false},"4.0.4201911":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4201911","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4201911","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-R8ZKtBAvMAE6937fqtiwBWwpiAuKDfuRIajFfI9SGt6tjqx7s5r9EYTaT+lyldhqixkyxomCPBivcmON4sGTxg==","shasum":"966da69294ce5a2d333e57b55af519e23682c046","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4201911.tgz","fileCount":184,"unpackedSize":2447767,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfdw8/CRA9TVsSAnZWagAAu4QP/05l1uNWKC6/FMfq3aze\nm95sJe2EkQsj/KvZaq0kIaB84iMurA3o3GsVmF9pwjSYDcD/pq/2PInn2dW2\nhXsqUt+J7RfR2duF4fYl2VWP0EqFhSzM+BvX55I6nO3BrVF6qEiDeno37mDb\nsvYT5+4FZCCYCzeTIwKD1wnz3aUFq6UgcsDGcZMmRm0PzLCUN2nUmlcUyz0M\nfmcLO4JpxXzkep4asug1OS8QrFi4LEEOlAtXOJKn21e5ZzP1q28IThVXS2UV\nEmZXqUZ03M65dwsKW5Vm8bDDPs9eBXjdptC32OGYv8kT5wwuk8JYCxVYVEhk\nOYVTmXwolST3EWr/enOnlbAX4BxzDDHDxn1Bla/fklHIAtPsAXAS/hT/mWxP\nnREsfBL8A0GNCHpANsP6kYTXBiWt6yEqG0gGz00/+MhmNvqw8GXIfJSTdPnH\n/Rb+yjsA8z2MhN6v4ELKVBJ9iEzQPikyO6SjaTDB95Wy6n/Penxbim8AmS6U\nceeRDkhQcz9pla6CVv8jzn+8NApM92zAOoHjYqInZAeoUM3e7yVLYVY4mPan\ngtjEdzRpDABSwz5+zyeUGAq3gMjonFOv1ISH4rHvG64+Dgyh8xgIV0GlMkpI\nQobD8GEj1koWipsXSapQbVKhcPi2FyWgS0+Cqt6xCJ+dSezqx2iMYjA+zKVz\nC3gE\r\n=10c1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCXLuiJz5jDxHNB7KCm9FQwgikmZqkSNcnfje2Ang+UHwIhAK5/1MjrTuU/01ZhO5izJ0oIgNJYHkfvE6GsF/uvPcza"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4201911_1601638207031_0.8865385343135999"},"_hasShrinkwrap":false},"4.0.4202172":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4202172","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4202172","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-uZ7rWn6lShEKe/yBcLgJB4KFLqYTqAg+FYuGV7LhdX5t+osC7BmbAQ5IeJEK2PYzhFVG0Ou/KZ1Eh64Rq9n2sQ==","shasum":"6ec39a5bd990f832b9ef44a3c0ede8103d6a197b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4202172.tgz","fileCount":184,"unpackedSize":2447767,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfdx9rCRA9TVsSAnZWagAA5IIP/j4RqWlamovzHhE67xPJ\n+mFXtG6loNc5hP4vjHb177Wk95kDLvJIUvV15AGRViBg533qHZyVZkfWP+zO\nsp3ReDr99QvdTDGc8r33jaARYH8gqQ2xGT9Kblq1VsT8xx7pZc6b1PXYYohy\ndpJlDmq25IIKV7r0wpeuRV5qhxC1KBL7j+IAtMzoeGmMSZDq3VZPlNBYrSVa\nP45Kew3fqVW6Mci0spyQzWp4cuO5YSsM8Tw+Mq+noD5brYGOElJxzlTX72yQ\nc7mKQjOoB4b6dXhCsbHBAOtHajugPNLGWeI227VkygWrgJzv++b+XOaQnYgJ\nEPd5PH85yv7qGHcIV6Y5QT0T3b7lwnzwjPTfshnWAw1YR7HPXRRuAaYZP9O6\n7A/cIafxmVV8YE3dAe80KvxNdl4avjrlYfskzKO0eSJvxECFw4g1Fwv6MfhC\nTh6374qqYz8/Cu93SmfFv+f826W5sTtv95zaUxfHHMW62Ib0DrLo5jYt8yRW\nWjuz9WEj7a8/cILXM2MKs+SmNUZTozUxXq4uErziTzgtNGx/i6iQYsccB8Ja\nHV4qkPnMVdvmF+Q1OllsLKxMyth8zecL1J0RrwLLAcYlRPyrnEyWBP/E99nm\nTQC69NmQyCyPUSbWOdoc60XipUIV+1vTmyyBqMn6ftrKme4tZQNsx571XIea\nnek6\r\n=4RW0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDULYvxFvGWQZL70CKkGbpg6MSiGK2KyNx7KPScJf97PQIhANZkWYCjfOILozz25jcLSuxF+HGD5iuP9okHcRP+Th3m"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4202172_1601642346740_0.8180657227275967"},"_hasShrinkwrap":false},"4.0.4204100":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4204100","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4204100","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-h0KpSQy0DfMlJbBJE/T8duXnzc7uG4LcU3TazWbAUVaZlSFWGSwiYHhg4SfSbzeGZb1qkLqHypW++AnowTQOeg==","shasum":"b0355bddd89d7e346646fcd9233129f7fbc47ba4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4204100.tgz","fileCount":187,"unpackedSize":2447988,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfd1IDCRA9TVsSAnZWagAA8HIQAIUXOXC9bWq5NuC9hV8e\nEIHNGJ8m/Tv+1A4+Q1T96CLEsNITrdrzYfBh+VmmvVwNTYkFa1rIlFcBShR+\n6tdyNGKm5+ErAbio/4Uh3IQSh66lCfOHz/yUqJYuGZ5JvxGNBzXE3/I9Sq16\nHjde25nhscmd9Zpx7DVC0GCPpwO9QgmSZ7iZ87G0lMmyoCmWVN4xnFG3YJDK\ng0yMpHQrBws8SDltJ2rUxcFHJXdJlVNpcv0PhU48dcD3jSVLCqbrwiGlFR4R\nuCik38zBuPu0MnwV/vLwvBSANp+wda39yJF24CIX7EFg0lEx2/Br/vRXLQm2\nZXTXJmqvVMb6Q0ymMZgdtuJ5KpAfA3Ar99l4eRVwlFSZL2ogT90mlqe32xHI\nhYAe+NxhxVBOYlxcNd8udzlYvSnN6q/zCccuOzTAxauKjm66OXMcEf6FaLqo\nIL5sNjdMrd2k09tkIHCirN+HBlSBVFp7mqszlillz3R1aN6DCzHqzb9G1zLE\n/2sVMF2znDnVo86EF2huUdv33b2DDcyoXmYIS4OcZfxeYZJxp59eIxx5qtqq\nUmAmhV4/MfWkylF0koMKrsqoq0dF4HdnewmP1SbWixqlwsLkl5w+Qd5/29W+\na3KrKsWh8fyz28/Jsq3XcDr9cFugxA5npre2s7Up6A6zngx1IMOHA2GOXJJZ\nYkCZ\r\n=zM6K\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAFwtls4pA+mkyxbsUNa9mRoeSyAnNCnmT0tt6dNyhEhAiBXRhubD+8Pr6bbwbMrKkVKI5vjvj86zhLqVxs4XR1CUQ=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4204100_1601655298956_0.7445587019796855"},"_hasShrinkwrap":false},"4.0.4207813":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4207813","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4207813","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-t2x1Z+Yv9ZdttBZcgIipCJh/k3jEVbDEQnstdIIzYAtpOc3BS+jWquoUylIWv0gXYK6NlVC2IZXoMjsrCYRhSQ==","shasum":"2ce6c4e34a3c9583ed0e8be35d8880bdfa2a2d85","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4207813.tgz","fileCount":187,"unpackedSize":2448084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfeu2wCRA9TVsSAnZWagAAEmEP/AybnONvoPQX71W0XFvP\nGYUttRp0NyXZ5W5IvSWev4n0+G5s2lJ1RXWqN8deCuAsySmHIkdobsODEpFR\nYyO0GOfa029g4psBXWFjPMR8396UqKbVnslNTdmEfN5Vcwk/Ua1jU3MQL/Qf\nALUJTgQVwjG82EiwnQ8xXPe9eSRM1ImNAIvIIyhID/xq/r+GcOTRB1Rp2DRN\ntwgEW77fb0knSTLJ3/p3P4+zwwUoJYWz8rBRRfSBtAxTSfgyrsnY6ShzzJhW\nCu70QAjDM+Iayhu+sHe61/KXwE6PWIXGf0R1I55WMAgyN7GeSv8DDUVsN0Hi\nQfQX13IlzK/OS+iliymWJkcP7gh4cvOiG21APhNKyRQ9LEGIODN6zS/vj61O\nTM+5uZvd596Pwo0fFjOa9zNDBxeJHUQM0fSU1+JuiQEBEamYAaPZjVHWRTlD\ng4t9uiHmXDCGrZabGMAtO3s3Dhf9orAXj9lxHHuILP9E2nMNk+JIgz7cvd2w\nmICqFpfdQFpWP52h6aCVnOpFS7tumLRCn8clEhyL4hoWweph77CO4iR6qJ09\n632wG4kCBk0SjuWYoHgqGB0/GPzTBLdnXhmxQIk3GhmR8bRxDrGekN0VK+nI\nf/d9N8LsBjlN30EloBnrpklOKuQacXUrq1CyhDSw14BoG7mH/8KqeAwrNvQT\nReI0\r\n=bhmB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEAFnt8OZkExHvAvSSKkrtOIuTBBWAaQdHUAvx8Y61HjAiAGUQvM1Xio+oYTjXtHB9l0kJvO7aqBLKzuRH+9GIl8sA=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4207813_1601891759795_0.9174090823245473"},"_hasShrinkwrap":false},"4.0.4208387":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4208387","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4208387","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-Ky5cdMggQFR++e/4ks1J1bjIrcEL/ZQBGtvZw+Oefon8ZhikCBdrH8KtdgGSC6YlgB9zROUgiBXPySL3fX/fow==","shasum":"700c4173f3065dc1cf06fbaeae08a41144ce9c18","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4208387.tgz","fileCount":187,"unpackedSize":2448084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfeu8iCRA9TVsSAnZWagAAME8P/0fM1G80Gtowhti08qsI\necPSvkgN9m+TxZwxBCB/A5wIqhgoc5LXrTOkL2F54Hy1DLOMn7HPPtsUhMXL\n34uZ6fWYXPxlTgtW4pPAiXPkCXzai1qESGe0fEUfTrgyZOUcAgDARpROiIIs\ncFKH4RYmFth31CAD3C62SojNKzQdAWSlHP3Q1SPxxRktVfweQobJkNAvE3CZ\nvxMSI8wd0mIqhQb135F8BSb/lCdvLfeJnt+LBg9hbCn/4b8Qya+d2Fd0H21+\nGf+qfVfWxkOWODE5hk4ZXjnS3WtGCiIdv3eUBbV2yPVhGvaw7eLOu1k8iCbc\n7TnpQpSYgAoH4jdfjEjg08RI6CuoRAahHfXiZQ4LovtTD4CaNMhCHOoG3m2N\nZ3xN/OhhK5WCAKdmfxagw0pJYZ1cbdejSregZ51IZ6FZI+2oHALaznc/trDb\n5ooYqVqdV47HpYhck/2NgkDoQsPdCAKx2NlZu4DkzPqBQ6XHI0gGtojXTlji\nbHSgohHUaZu4xWr1s2wnhn05/Cun4lW9saSPkfvq4BIWX/YFGh0WZ4blxd0h\nDkh+rEawhASca5vlZfWr9V92htP+Fc8XvLjfwwMqFVwa0guih9bfhVxk0lga\nd2LIHKFRBgyQO5mkboicdDyHNVHH9qznDXqtUTb/2qXMSMrkRYtAwzJK0ZEU\nIgTn\r\n=hU4Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDgQOnW+hbFFHtcVOFVdl8heuRQ8SmWJZVQaXY0P/lbvAIgegwG7kgMRIJOOD9X2ryOQ8BDhijj3dj0nW2T45LSnBI="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4208387_1601892130100_0.5431795042489851"},"_hasShrinkwrap":false},"4.0.4222914":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4222914","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4222914","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-mf+vx/hUj1ppqjG/iFdpY3PcaQDJcLn0Et47biac3qZgCanEfdcGyke6kfyC2Xn/attZJqGAGlzKKMJ+/Umabg==","shasum":"714a102be615f1d9f54c9558e2c91ff6ff868c77","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4222914.tgz","fileCount":193,"unpackedSize":2449989,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJffe1CCRA9TVsSAnZWagAAv8sP/2QfNV+2zI/r1SmMPb8o\nRPtLgN4ol+PeBNoAdL+8GqYAp225aRk4m1id+fozCqfhrfrLlLpTBv+FH8S2\nnpo6omvrdUCyEBSjw7tQKZwpy1BGr0IvLnndo6Y47yBoDjIqJ8x3oRFjZXHB\nLuLOLwjrNhrbGuG2uVUl0n3GOCMV9hqEPw+ymHEIgt76XduOTuNqbSM3Rv4Q\ny0TanXEv0ZFc6zkjXOJFUyxXNrXeqk5Ai1cpJ5mheoHNIHIrOht0OuHr5kHQ\nVg8oBiNiBXLa41w1+YxC7rrpGOiFGdWpOseu5D5UuUuNN1M+dnCkO9Zh88HL\ndxWHrpneo6jqWAxndC7EHmxY3rQxa55wWaQrc4JzOAFfLivqPhztXc1j84yY\nYoKphqVRyyqk93+c7bp8rHNgSJYtbCF5CBnDE1f/Pbfv+JStxyi4FNKgsCFe\nH3jjOzYDjtNGz4NC0X5hUljIf5oYiTKjh7+yDv+to91Y2JO12tBVixgbFqKC\nTa660yWGMTykxWy3Y1KVzRvaZ5RKwBFFHCiJ9iVObRkInavjYQp+0wmyezwB\nwzfQfVcSj3RarAHkUNAETFhQHqIXvTVvzq7x9oVxPgdmWSXm4GGbERi99MvH\nvJN3KUjJLjDOcb5q3YyQEOLCQD+yywFNAdWa2BGLr6JsbQ8ldzRIxhmIffHz\nDNfF\r\n=6jPZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFRgpOJ39x6fAhyF5Ngc6tl0Mdortlfvfdf1irgu/nFPAiA7cPwLvNPCuhexbD0YMQLMGRgWi1THjBsGL3QQoCK5+A=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4222914_1602088257786_0.07101492706248869"},"_hasShrinkwrap":false},"4.0.4222982":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4222982","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4222982","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-9C44EAyih+++tLRPlodYDUxX+Ac/DYIUBmNfwDBi2TW5Ws/AxkpKW5LnwBFyx38+q7YxXLbF0rLqabfMfeWE7g==","shasum":"c1f01a170551f4ab1d46bd90ca3a787c18d19b47","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4222982.tgz","fileCount":193,"unpackedSize":2449989,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJffe9pCRA9TVsSAnZWagAABrAP/1qfFVVOrYNN+yd0963X\n7iOQbVNcN2ZJxhtrOc4Vp2Z8ALbM9CV2YARuuEa1ToPBYNnmJgspJdBL5U73\nx2uw3+LKOeHIkmNNHsST+Vh9kcjamz81nlBAkGnVP/7i5LU+GYhT8D0YsZwn\nnPrDBf5gvoaCUE+IcPYWsXcwB4/I+wqONPDVgIdnGhFOV0gsyGYijblMDZVr\nAUebL1e3F1ZB6+rhH+GUZ2doaRmpTyk1e5yd4wXi1dNIguiu5mAjOs3qlrh1\npV6ohlM3s27Od/G1p28mmU4beFXi4TaCdRw4bErPtKb1R6blBwOfMD+kU0i4\npERwmaGGkFB5QbTop1b41IPxMiIFKecC1taa40VPFVe2T9kloDU3NhePKvAx\nuDfh8gkmu9iSCrITNoGFjLi9aJkbYZlcTY+qP2IGIO0Gqm9z5yfaihDcCDdR\n9/16LIzKC8HRkcPRLUR4IBPxjagBE396/zUvEfmRO4Pva5VKhJuzD9+vcVqI\nDXI3vI3p0CuLPxx30LTX3uIEJ+vyeKCdQ2SNSpOnkjV90ZDTtqdN58aR82IN\np1PWxRxxaBRTWMXAkojsFxxkefITPvDlurPBkKJbcgTwumF4iT8MN6IF4kx7\nv1O3c4VBZ8U9gtJo306ZADhilA/yJQy9NnXRXrh9rATFrlGyOq+taxE2TuhZ\nk7GD\r\n=wGYg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG+xEJSRh6omZKVa+o/8Reo11AvulZpqEfQdoctf1LWtAiBlEy4rIaobehF1sQIGyxW7AcJw6QOW1ZRPc0zObBBpJA=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4222982_1602088809269_0.7886750189767984"},"_hasShrinkwrap":false},"4.0.4245019":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4245019","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4245019","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-CGRRSDRseHpQcdE+D+OcNDOSf6zaSIntt3T9araNlEnNJWwzALjvRf8NTHmQP2wZldzFZDiWcZjK73QDusMCZg==","shasum":"ee219eae525c8998379234f509152b908cba3371","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4245019.tgz","fileCount":193,"unpackedSize":2449997,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhYpnCRA9TVsSAnZWagAAOeYP/jworph6uQpEmMJk0kqu\nudQdy1Sd2cVUfhuBR4zJdWyf9gzwgEbEWoIuu/4dtwgFO8j81PUnCRJHvvoC\nYj0YSkxFNzl2Lx9600vpf8RvRw4/55ny6Kt4BqQHA3yB2gGAYTusXAWsoiZ4\nCwIe6ur+Lv99bSxMxcN1Wax1qFrqqAIBqBuSMbzFMbbkpOG8GtgILGp2Tbwh\nwux4vz1MHtxkOGSA5DBbKT5dx7ruRP5hvx0yggGaVN/F9X6qF36PjcwBtueT\nM3oPYVSPhbKQ3wiU5QTaySCXkwUtxvG8wZskiNIHknLZUn/DW2aUFtVSmf2p\nK1e0vLDXbsfhUKEBLdRQDr4avYnz/t7XN4Q8DOPu4hTYtTqAtM+SGr2YD9E9\nvEAfATun7s8PEyQZXFPpBh16j66rhxj625uuK3LtX9b0xV/EK5gmt6fkOruT\n0dKGnWCQoGCBUnc8Iugu1OZrW8Ylvw/plEIeFLMRrIaqIqqeyWSWWBdOZDXz\nqaXhFqkmpaRT/ZGO5wdEWliqVHYlWpnNohWyNh6inoN93DXDDIOkmh+ZZsdS\nYlxIM0+oszaZdQbqWIUkRde6QKtO4/i7jIeVVrAOR1+SAw1hU9lvie7MnLNQ\ncttFE/aHpWisW0GGBD0Ie+hWPf63Y2I2mhISY5/KHYzrxdmrcGWRmODVcQKy\nAeis\r\n=PZof\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCNQ2EfiYR2/YHWiCrOYkGls8fJh8xx1HGjP+evP3nJHgIgUxv8k86eNYohbFZvB3QmGzWaOzCzeLpHVgXKR3Uu6Os="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4245019_1602587238832_0.27201842349668026"},"_hasShrinkwrap":false},"4.0.4246970":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4246970","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4246970","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-R5EPol44L6UWtmwHULHU1yXgbeGjocEUxgRspt3X0IjeRY0sP4s+a0g3RgdyTqcfA9WZYrrWNVdcOkeofXWU3w==","shasum":"1e645ab4ed902998c269a36515d97d3bfbc480d7","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4246970.tgz","fileCount":193,"unpackedSize":2485777,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhc4HCRA9TVsSAnZWagAAKiwQAISrI4Xjn0Y8npU6MXTT\nTaFIqdXlOhYBo5qvJ+gBxi/2L8LFl1tmIf5VlMQ+cGckMUdNixbKibrZqXai\nIrRd2p9CG37O93OofPrObwBz2sJjo+FNLV5eUTiQVnsRSDwK7v2ao84+xEok\ntY9JFbTELgzccT06sf5wjXla3IesZho1+WKYLJfcdvlMdGFS0kNU4Ya5zlfu\nk+vyWyavrwWTX8kidiU0QISxLDopx6OoK+irqGNGOJyf2MBLT69cJUBdBLJ9\nq2QzMUYGhFc8bSNjP7IoTOmijhP0iYQiaNH64UmRMU51eynWrvWvel+oSHy3\n0uDgXZtnkS8WkAZfWLif7P+p5EPCiMwQVxEY8w5DwurhIU419CQpC0Ks4l65\nuo/F/mahTL/udi4cmpv4aDeM23zN2nJyZbdV8xfxYgov9CTpUpiOlJtG9b2I\nXPJJjMx2pPvX6Wwbw6mjiD8JETmaznFq+ehteqSXJAvkd27gLUecsi2LSrmA\nh9YsrNvVYzqL5BwDadox7cvDENOSYkLl9UGOs3BMxdR/r9xFBCUHW9IEAeRd\nCOmG59Qjh3asWSwFZ9ktqIt5R8lQ+cAsxLilLdeoxEzxVV/rgX4fey6DsUJ8\nPdzcdEsgAL95wTO9LX5XbM/TiCGGqU+JbZlCmQXaP+Khp4ej+iE9b8e19Yzz\nj3++\r\n=jqHi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAOPHgcdY/ufSpBNezPyhXpsri5qGcKM2havaM5uy3dVAiEAmb5czLpzuZhFU82jsl+ETL1FoarOp0JrkjwjL222hZU="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4246970_1602604550675_0.5120001587896219"},"_hasShrinkwrap":false},"4.0.4247642":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4247642","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4247642","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-0HsFkcNddw2DtRVpFnmqLa2zaMduzEnPyPJAqnO8pr6SK/j4Yeed633xTqmxtQ/FbR8Nnz71CZXMnS/bsZfGPg==","shasum":"906f695384d718016455e5b80637cac5bb17bcf0","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4247642.tgz","fileCount":193,"unpackedSize":2485777,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhdT8CRA9TVsSAnZWagAADccP/0Keor6jtIG3wfuI9v8m\nVa4b09uRl7fuylrQnMJpb1msCe5Gk3t1Vrk9w5TpYrN17tOxWM589EFK6haB\n8OZmvxP2QxY2CkFRC336s4wP/PflajIanfs7lvexQhAeVERaXHd3OMODggoE\nEB6nelmSWwa8FNHFbXNaHxp7NtUwPWona7lLEua4olDVOcb8J1diX7iu9IV9\nHtZGMzLavrH4q2k66roo93NKOhjsjXvl7DhXtb678hd1VE5ywKR2jVaX/zmb\nXa6QZDE/Sur5JFHQUWKi/FXxoLPasyTvj/Pi1oSVSDS9bVHzlemHNhjMYzR8\niT/d5+AFYEUFm7ndnDj6anXhRdSjjm4dN3+eJaAnm95C9whATEKk0IxD2PdY\nZSIG13TihVFLkPxTlkXTM6dW37zkLN2Q9uFSpXhQvqSCfDLu+I8WBzWOhseq\ncFogI1FavQN18svkTrSsoK4zzhhfMWwgy8DkMT/FJRirg8F/ATznB4APd8+z\nijpnFGuRg8kH8/ge2EDI+2NdEPhqarekua4Vb9wJGwTAB2cg9enwabTQDuuv\nNXXQGjAsbhmnDCD8CylBS1ixSSbNPrB9/j47GZOBd/szpeIRIGyHnbyjMGJt\ne77JYt8qe5L3NN0qXoMfD4Gkm52MMPbRFswwvoHCuBCFrSlHAk6o+kFUOfBi\nyxBa\r\n=bfTf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEe5GXKRmJdlcQOvAodozyqFta8kc10+RbmRE45XLCQ2AiEAg5+pHRcR7gI7tvSH9ZS+/QwCdWrmHF239E2AmhttfsE="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4247642_1602606332201_0.7742976542215254"},"_hasShrinkwrap":false},"4.0.4251160":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4251160","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4251160","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-6LZIQsZEDYa6/py8B/hCKzb7qIWRjb8IftdqR03GGHyB16/muqQdfmJBkdsZgTUs5JpBexZc32pd2z/yuEuRBw==","shasum":"4c1131856e61378b71a2f947be643ece232f244b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4251160.tgz","fileCount":193,"unpackedSize":2485973,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhyRyCRA9TVsSAnZWagAAEG0P/2w97Z+BcEt9wWYY8KDJ\n6bAsGlQ14+0PHtKvqFey7Ty+4gnzxrKL7D3MDfmXKh6+33F1pr3QE1XpH7Yq\nPe915kNNKkm3LfynbgBNzPKkdO74842HDmCmmPvtFEyk7oFPkkC7te68RGKB\n83W88pdh52vRwP+T2MxcTIfvNqG+193ZKnwV1PcSG4fjIMY8f4nTo2iF4SvI\nKAnGz0qURzg02c+Pl3rNbnHf9bugAwcvsR4ruVTAW3a4PC7W457ma8X0qacR\nHIxQ8HE0rxwyaFWJKPYxBKsgP1xOiZKafGQI5ENKJbs0cWmdQTYydCa0drwI\nykGLY1gmq8YlqjV8NXdraEXsLeJQSFgIaGd1lVdP6ekHxcfybmJS5jaLv2vz\na6ye2gIY13DBJ6FEYmbjWXaJXqkmDCIYlQjRD25Q4Zt993c9KbaVe8DTps6k\nK7gTTPFQm/WlKrtmlCO4JQXrmvaPScFFJkgxhHZGaZI2QF8q7ETBveTSagPk\nYHiZQX40oWsrNUXKfSF2x+tTKzu1hL/8rRuaQ43QLRQa+BMmhrwwJR6Mhsfj\nCOXDC8iaytOHFKVbop9HngwCAiq24Z6V3vjRiAVdtA7Y7Xb9oXcbyzImGtMC\n64XcCZjqCx0DMNyuskjvMRfZNDQXNM3+7M+V3OPHCwfzu6QEj4rACySIw+k7\nDro+\r\n=Y+Rl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBiAgm+l3igAi7g3+mT5fsRJGfIPNDVuTJW+ke6A34hQAiEA9Igz6n2HKtEJug52KktwpNKSwnMClCSzDo3tvMO+e90="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4251160_1602692209436_0.9117441760853942"},"_hasShrinkwrap":false},"4.0.4251193":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4251193","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4251193","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-QGPqS4FbQXqYBkzRa+NjLOFxwbVUUjZN3ghvuWB5BU+FRfxEFyXmEtmeS8XmHpdbgv+iz28mo35wanN28dGuAg==","shasum":"6fdbe73cd2ef8acd8943b4121681d952eeb6166c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4251193.tgz","fileCount":193,"unpackedSize":2485973,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfhyXXCRA9TVsSAnZWagAAqpQQAIpaPRf4PIFenuhJkl24\ndTxdTChj5omyrBbcJFDl31vDKt3cwQc5bfpAoGWtVWL62ZKdVaRDndMPTG+5\n3Bxz2fdp7ubreJ3IIFQDTzYp30oEzgjxAxTkPgLU7cEYvBHEd+j/JpGTDz26\nSgdpY9Zy9IPTW/pRx+k9U/qyniU6Z71iaL0FPYX2d8UiYctbdBkwlg3j0TZc\n1CUFLxFLHTbf70+619/hgYUiitjXgPvNPd42uwCsgmiBVDm3vGH5HiIZGXoP\n8lN5fd/asNywWRw10guqIxQ7jSC5llK/JhYAi8+pU9VnINjH2mJtIcOiIGtz\nSSbfq1HPc75Iw9c5cJ/CH8jwa/GGZF+D6xgRKRwhCpFBRRz+IwrB/KQy8SHc\nr8qhbm1nqK68t+51l38LvLCoSC/+NO2mbnW15FC/LcfIZ65+Xllr61Mpkn+i\nlgFSLDYlKGGr/IeBITRV00JG0Cot5qbfj+JwFXPOHWguBUD8fhRZxbQO0hJT\nDztzdCMsHkg5432TApg9w/3I2iCreR8lzFJ83XvKK4lRuMUn4LMJUJL5UA0L\nvRslvCLHfMYopoSIcsMe+k0xSh/LogXQ9ldqN1j3ibbOHob7u5kzrJGjXI0C\nB31WGEddKGprFHysyTPNsmaivFOHgAMRaL8iiRdIrimWzOq6kuxTTZJE1qqa\nsMEB\r\n=OpZr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDh+uBmk+3nc2VF2hvvRj/HddAfQxGhDpVqUZsqD9Hc2QIhAKxHE6QS7Wuw2ux1DtiX8RMdzVTG7Mb2g9i6T67KL2Io"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4251193_1602692566765_0.8815116271211219"},"_hasShrinkwrap":false},"4.0.4253933":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4253933","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4253933","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-5LkMiFF3BiBvtSMTep0H7yV68zi5xuyJ4rKR2mfwMsHQbFjqTmVNsT75MFd+eY11RfQ6OSYQ8UleMo2raAj4Yg==","shasum":"3231410d82494f39786dd3a53a1c938e9504ab85","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4253933.tgz","fileCount":193,"unpackedSize":2486294,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiDznCRA9TVsSAnZWagAADkkP/iI9SthNAtMrGKDJ6PAv\n8qHVzsll8ybyjZAF2xridnAbr6xSCr5R4CyGOENq3VRFj+LVeRNz92QFA42L\n4sY11AZb0UP5ndXf2vPI/A/RpVYbOgjLPJ5W9w8FLwDwAMlOxrnLYMsKg4pN\nQbF+XsSKALBYDsXN+BQMcItwxlH9UZ/NmnPTyWjfpcnS7nUNpVlBkuGfOALE\nU3hVnwNYyFaiKSPK8KJNSI5e3qJrawOmVNHpNZLvsLvEBs7L0hhxgEHGZbRw\nfbUJ1MHyX5xokMJ9snx1ix2+Bii2UW75mfvBa3P0SMmNDuM0M6LrSZX2H+8T\ncwYwhZqxQhkrYa0i0gTgQYTIB3zTVxk/FNBCnsDTf+nKxOi1qtpnpNgLSDpp\nHKRLMT6zQkW888RDgx0RGdUM+lgEOaGykT7Shm68aeC3eJ3OwqLzrnqUdlwS\nbUw6qn7BPgdxL5I6YECT7bEJBauymEACdPo7AxmL9Uh/DBbS70Y2Zg1nyF7I\nJ4Yuc/ZNsp0Zb54lHTBkKl62VeDMO6RdeBkDAqpbBzKof4SqwlohsVnHhByQ\nKhBw6cTuXqK6ox2gKA6xNveSaDvpayQ6LN7JOt8tCY/7Bt91ZuwqAmMOVyQQ\nknkedygc8VuJelEorCNV5ErRpO7JLwmYUhj93KrlqkGbTQyUYMQXqYbAH8Uh\noi3/\r\n=JFKi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDt5plbF0VIZq+mU8h28escYK33b+tYAaNT1Oo1CNAc9wIgMcJNefWZH0akUIVOuYZEdX3LMC45OOGCvDBXxaAex3I="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4253933_1602764006549_0.3229353528399459"},"_hasShrinkwrap":false},"4.0.4256044":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4256044","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4256044","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-gc9MPNXwtQO6sdZ7tuAUeFrFmjvLiNyPTEFGnlOiiQalOh/Ye1VqeLz2WOr5srfD1wa1Rab820OZGRvbxcS+ng==","shasum":"fa2fe3d0f4741eb0cc9346b27b0f87faee8f560e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4256044.tgz","fileCount":193,"unpackedSize":2486294,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiHWvCRA9TVsSAnZWagAA6gwP/RHrVuO4lQDae4o4It3z\nmCvi23xtZ+3wLWNf7rf0SCCasG6tarsrW2UozSzByglInwEic2drsKJ3KwoZ\ng4Q4cDhWm3BS/NoBUeD8nRoV5rbu+A+3wFiO9xShq5j/ZEf79opcgDSXLkl0\nMp9mvkckciElSO/c9KNqw3nKTR3KKSbcdJBfuxTh+vPUgrBLlFb7REfC0x8D\nJdaw8aWAF4BXEybMCo4TMjHO6jl9W0vVhurx/6W93tiAB0qdKgd1aEwsCvtm\nHWHcrJ1KjBixPEUtkB6ddqP6WvEO1wSqZNr/DpEA50mt1evqBVoTkUF7/Kun\n4QQYCKNVho6LdrsVnf8XhYts/HXwY4wz/HYCOJCkQhBGsKVRgj8L+IIVldzF\nDJuHBpjBeF1etpMluc33xjTO2J7ZcTZ/iu/M1yao5U86PdLJo49QycsVyBKq\nZvZxixM7LdW3b8hZYC9SFIWiWjO7nzjyxY+fK9+Te+iD/WdaHOIQgxc6ByBs\nj9VLcwC1b46g7GoNJJF78UCaoNHCL+EyhZpM6O5g2IRLGXI/gTHQbsimuON6\n802Eg2+H7+yGwtYIis8NKh5BmXeHG8l/kH0+syp6qma1f6m2XAx5+6mBXhX6\nWy72JfUiNpgu8eeloZbCB9VnZ4qzIFM8p6Qn0CQsZc72UKNHvmmDmHHzDXuu\ns97+\r\n=83H9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDsSAR7Yh5Whz+F9f0sUnmbchCdw0TQmS0mHEDnt3vTKAIhAMnyAAUJkdcrObGwJ4uGX/oyj2nW7LZItIYTgUesKMps"}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4256044_1602778543090_0.008573823934885816"},"_hasShrinkwrap":false},"4.0.4316294":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4316294","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4316294","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-qsw+uRvpF5fwGvE9C17zB5mF+o7LTzynQKfUZy9KF7frV0TwVJgz4pFF1HjP0EUf0XDUX2JlI9sfeUViRNYU6A==","shasum":"9175319692ac49c5a02b76ca443ad2722bdf6805","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4316294.tgz","fileCount":193,"unpackedSize":2486291,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfnCQ8CRA9TVsSAnZWagAAoZgP/1I9qO8kubbp7AdWLEGo\nKzKVzlWIvOg/5tPDFDtKtq3oIjrydreWAqEc0RPZOu3Iay99eHeINkNamObM\nkIdK7jFczT37YMaScxAfSptiZ5m36biXhDmpJQPUwOGugA8BE8C7PDCWYzXj\nrwfNKKHAdRkGs8IAyys+VDPjBE3fOqHrl6B6WOTlIXZav9H5UL2NTU9gMFig\n3InS3IKZzLLkVnh59pdqeAba3ax0Xo2ROzNffOUbcK1NYpQ9pw2LB6ptQM3h\nSUCr0o59gTx4ZwMUXAPb6HKIwHBiA7LQsHyJaSpCJ7+rDn3qa9Yt4na59U9Z\nvFdzHhK2RHBj7nOFcFRW0Jd3o7fmBh3q+/O75WJknLprFFJj4ihbV6tnHl8/\nJxRVOQBRLZ05n1zkIBn0GGXFtRGkbk8VPi8Kia/I2TCFFjBxRjbj3JtvXQac\niV7VEOml5cMwkRgeSEBys4Dcnl+gv8AY+g3X+XS/NaTaxZaMNRy8aZzemN+E\nnasLnHpddn+H2SSNNTeb8xmqG01QyhRRaPOat0dqVQqeX8fc5+z8MpEbNmdd\n3OvZT5s4bRHu1G2mpo2ONEGk4OYY46rCT7AeHlLyuHBtvSUqdjWCH2CGLoay\nu6OhkeCv3EjOGen1mscKmIwFxzWhCMWqsOrsZbEM31yHAHt1rFzwRlUYrz9l\nupgX\r\n=fLuP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEy7iY/5MsxAKJbekeiT37sZEzMioKSXInPQbgOps2aEAiBtMW0cBE9ojugDhBu1qasO+4D5hFLQKugs6KwulzvZmg=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4316294_1604068412133_0.8099810040234365"},"_hasShrinkwrap":false},"4.0.4317827":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4317827","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4317827","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-zjmOIpKhXTbBS8yAWN/M4oLSza8Z4Bjt03Qw1LIRUSHETNemqpy8Bu64sDWnN5klP6d8n1w29cmKdZvZDMLMGw==","shasum":"6023e6628132216a2234c1a3765d3b2d56b70e84","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4317827.tgz","fileCount":193,"unpackedSize":2486311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfnFntCRA9TVsSAnZWagAAFU0P+wXTvqPC9yCVik1xQfgF\nCdHHA8qROG3NcnKijh6XIqX7CFhhDFCFsRQItLO9bPEOiBHj88h4loPWIBeJ\nA4W98Eu24G4XWi8NlxiQ9d+0bwI7Vvvz7ugXog3cjOb1qcRzKkqDUs3kmpBW\n0zB5Tj39AbV1Bf6y4uGKQ++8fIrppY2IMbWV48Jvi/vGvjgpSyO6eGdKz/0K\nqMQqN33fAWMRi1bgnQ0uzVDSPtDbDcu7K/OLiVy/pE+aVoRVh6lZtL/of5W8\nFPQOBhOuH6KjNewAvxDE6e4EkZpb0TdtCjCysmrL2zw2twgXkaRGWuuGZKKP\nJmOR3m3MFMD/ZCf/P2srma7NqsLZNXlCu6DKlalgBvHTCdVfri/JmYJMIh7V\n4gUT3RNGvqNFsLvFwDLyg5qS45FfZdB7/864BsfXc/wUv9+5nMb8vULHrus5\ng9AEoDCMYD9jNO1+CoKZxozb1pQ938ixBcfN5KrLxjzdMvnerGzptg3zXvyc\nHxpzwDRzCrNte5JHKnjpwdPR0dVqG742rL60YDR4s3p071QVwfqfkoTrej84\nOSRXXEPxMmgLo5daGYSynJVz2B7gUtdJBszZtgqqkGEOnLBfNPvUjnkkLKHA\nh2KekDvUS5g4/DlyRrvLg9vRB4NYc1e86SV4Gq6bt6is5nF+NKRSV82yCl6A\nGkhS\r\n=o0ED\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCVnLb8XNPYOypO809rRJb+kDsRe9A+X4wM6RsTmb17lQIgcsPHdIroLRteIyWR020C9880xruda2naBegH3wiMcaY="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4317827_1604082156438_0.31501239543144566"},"_hasShrinkwrap":false},"4.0.4323692":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4323692","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4323692","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-NmW59fnjKlVSMKeev6gEiznGMKC1tQZelLzGfSTjcHueduY08xSqUwg3eWVRHvcm19NjnT3BVTDZrlyEeY/YkA==","shasum":"6b88331595e771ce36ae1103f1e0093871ecfbd4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4323692.tgz","fileCount":193,"unpackedSize":2486345,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoSJxCRA9TVsSAnZWagAArwAQAIhLxBn5HHH6ewtN9WGZ\n7muR4Vn3ryCfpH/4qUbVUzZQ9wRzRyb61k8ka5+gdS7IKXgi9buD9kOU2p63\nnDGcKV9MPz7N4YFNT/K1vTGJXn5rYilbkQJ3CqIY4QmurFmMyJ9oKuyAyDOe\nutUXGlhxihMCxsICTb95C5CGcizEfUoGs+NM1Mqmi+mRmAwhoHXG1nrJ/5RZ\n6Xojxm566WgTRAAUByggXyUvmv3tmykq/VSZq4eLPG0EyPJe9XNzTdMF/SEq\nPBDTEmzZ+I5NqasUYANEOBqyzOSuRbHxcV7FM44qhoFJ6qGrrG+4akJEKnQ2\neGQdQEgeRJ+yrm5W5qZsVWayEjb/ALcf6SiAveyrluQD1rywR5HGC4/NYV1X\n0eonRkHuW2qJfOJxquTNj6SnKQk0SaP37Pd7xaW0jHxP2TDnJe9PQHwFUxFh\nZE/9r/CdAIywc9Kc+RPPCiIYIxLH3zC9kagmyjO4IaAfO6HhEo8VwIvBnBFR\nAPYsrAZDN8rxlENjQ0V1moYFU1UmCxVhHiK7R3aSwLzMxf6lQpqKXCdAAvml\nrcw/7ZvGaAkDQmZoZqgnFVDNWSpGsr4khyoLwP3k7crIe037NptKnrRgVRvh\nA6Wj3yHGfLQImqnyhbzXW+MUiggHhH/SPx6tXLI9I4YcHb7eS2ljib2ZV7tO\nv0EU\r\n=dr3q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB0Jovwzpq3FniQvBqU/cJUvQlXV67XjvWS2YQ7cR5uTAiBuoZ7JbzEaUYbVKQFfkGOYgF1U7fTQHeV3cO0B68YD+w=="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4323692_1604395633044_0.49450427670208197"},"_hasShrinkwrap":false},"4.0.4324944":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4324944","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4324944","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-Ke/Tw7TeGQlt7rcIDZutg5Cg2yvbTgg8mAD9oA3kMeSrqSha2iwaxEtVL0JWYBaNqjwALC0zcaTgPyLWVQymuQ==","shasum":"bd76961c47674636f00631ef0e1fc13a4c36c8a0","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4324944.tgz","fileCount":193,"unpackedSize":2486345,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfoSP0CRA9TVsSAnZWagAAVgIP/0QAXHn4McthVf5nPAnk\n0VaLA6gLHpWNv9yDZDZjVVl0v7SZ4qvbK18VYC4LYoZaEGFhDkeEo10M8oyu\ndTrxPxdL191hXzTkdcKlYO5jHI1FI6jEYDINL92JJExXVTUOvDuzyI5WldJA\nBLZ/XkL3jEts9+i1iqmWrWgZdfzMb32RE97JT8XfmdVcQkFnVsVMb90P0Hu5\n5vquEO78ARLOWl+jWD3B5xmjyscfhCbjBajuDyBqpwt6Hjg8DP++FS78JH/S\npm/VPnG8mTxWa6x0f0HQmwL+mYaJPibzuGjPKb5KGtvEGJM/9Dwtuwz5uXJr\n8XfQv4EYnowC5m8nT28fITS8m3/Rk12znOI93e+E4TdNWlc2ARQ1Q+fiCQkm\nZiuZI6nK2tiYaoeNYNwFYJ9yoIqKntQWtu+kpxDhaeLP0Rk/tN3RtQrK2wZx\n02jhi3yxL8mP0N3LYjDIOeMXVyo1Tj4RiROe0rPCDbqG/f0M651xIHnWc7XJ\nmbbEpMR6j8tnQaMNCchOnlVjuJsNzmNn78LongRsJyWqRGITOX+7d3ey1tX2\nE0hGmStaqjSjJ+NyI27i0Evhj9s1jkiEkxKQudPR6P7gMrnGVEQhU8b7ycNe\nzDQNwEFYZ1gjSS3fJk5OkbKqQPysaewTSuyeYBJ+fyEjl8L0XMpZosbYFgDa\nz0b+\r\n=JrUq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCf31ZJF+yL1zjuuBoUfrf6JHSsxcB8WAVS6aXS6v8yTwIgUB5ET0DgYjLCWF8z4OaSJtXUqzQUWzN/AGfjMcf7XF4="}]},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4324944_1604396020448_0.3145989401525138"},"_hasShrinkwrap":false},"4.0.4331115":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4331115","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4331115","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-1xz4MyqXLMeHHhzY+WrHi0dWEaHvukXrTv4n5yslPPnQ5I1nuYALH4uI66sQAUPIqOw0jzmYRKRvjLNDCd2VGQ==","shasum":"d8f7a18fbae6a35aeda3a723fa7d75b7c46d2550","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4331115.tgz","fileCount":193,"unpackedSize":2486799,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfon6dCRA9TVsSAnZWagAAhMoP+wf3B5yAyNmBjPK1bH7X\nZMaaoNgA/lZVPy8ibGWQbmYPrA6+bk3ejNyWUNaL0d/O0cQELLhT8TT1LSZX\nkyibLWR21qvljiSTDLyL9dLuuR2hphSTokc2w/hJv0sKlFSiKS91OZdRHrtH\nQH61uClW3rnKn7FVZHX8t/J7PCMdk1XTVxLMZI/qGzpSHHxtYyuvEskw1CNU\nvwn/LTSUAWPbDgzX7pWS/OisFEULEM5Va7eSx7VQyDkqVwM9boc7SSlMWY2l\nfzMWpveODkcMVWCc+E5rIptfG1ypTr78+upDyzj5klCT++iT9HKbUaD+oHoz\nrpw/IPTj14k3PLVgplVjutvL63wWI+9YZ3lbnuH6s04YhGNNZJOJvPFV0ekW\necRfz5+vyp2pxzTwCh876zQQwqQKwZYWKLz4xRFVtjB5Syo9KGb9vFrbjpjw\njKC1B1IanibqbftwVkDaAav3gSbXvol8Zu0gEeMWZbOnfbpUousmyZ5BBYKP\narkdfKlvqssL67UPDYrLLPeMu0/iy5dL0/dZ5aOM43XN80xBp+Pkzpbegebq\n/lULeiNkHhRPonXJN7nDvQKUyQBVUs95O2c9ToW83ILFZxbuEro9pEZq9vqR\nAl5NTS8lymdr0A6YkNPLwiacnTXrIKze5qhhAi0F96w1mPvhFmjy40Q7xJ2m\nS9V8\r\n=V1/I\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICmt6IzO8bpdlVK+BghXxmZ+6ssMjJHSQ6fy1IfHvUtbAiADy/xIY01/C5rPT+xlqJMCqNKvRO9WmkakfdauP+9qTw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4331115_1604484759072_0.12313408941157156"},"_hasShrinkwrap":false},"4.0.4331484":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4331484","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4331484","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-+fqURKXp1hjqrcBuZG4G2Wf1JeoxlGDRuyiKqRvc97+4kMj/7mreCSNAF0uE3V4TVuxOwgU7MAeq06BPWacmXQ==","shasum":"6a66b17ae71775e7e18e59a9005335d5a555a3f0","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4331484.tgz","fileCount":193,"unpackedSize":2486799,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfooXnCRA9TVsSAnZWagAA+XIP/jeNvfFYaHZWrCvPkQh2\n3FCV/tDpcXXgpNLSnJN7oXb3RKBY7iQZqYIyRIRxEMs8I3Q9E1/YH4Chpxbx\nVHIe1q6s+wwi7EyQWMPvBwoRIXKr5zd4WrQ3aKCVRnH3Wp47p8oC9GH3YRH0\nIfZfQNw99/jHin6Eyvb/d8/Bs/5gWMswD/m2MRRH5qYOqHRThCWBiQE/d4af\nO1tRKJyvqx/XsHNqxpaGNENWk9qNRmWFE+uQmGgMZfFhadqsXO1ErNcG+CdI\n2VVNk4HH/PSnKoF72zuEUWTAz35iWjKL99JurVxFR6cK4vDJTu9ZQiM/YsBm\nQT+BnqpKVB5Mb8kjmsBqPvCbfJj4hpwqndcifVJzzXPeUqPs2WcLbyZjxFRN\nRUKwAwtFGKCv78VPzos7m+mkGqrCdxiVjlYRk1IKvNfbD9KAyd/cQHhpbERp\n5rz5DuRnZB4C67naGecSnxUoFi7YGbgnwmfifVyGR4zRcvpCCj6quqhDYvyl\np+0RshP4YE0SaLkAzgTP5EbKy54adq4fieIUm3468TZmTEQdZk5VWb9gGZNq\nkHSK9AJvK4JnCcGJ8sV1E+KLsQyBdMq7KEiN/NIbYizi9cdguZvdL1P7c0XP\nYSn7Ot8U7x57kkGMbHk6Pa/UvWmzPhnVkNP7LEj7kDoYURUo4UIAPQOI1TDo\nyK8b\r\n=oOWd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHEFGWdk8b/XdNGnvyvlsJBipH+x4j8oKMtWqI9nJFB+AiEAqSo8yvJCg6dg/hqlp9+POgJwJwZutmjej5xUjqlx4qQ="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4331484_1604486630574_0.036738974701454596"},"_hasShrinkwrap":false},"4.0.4366893":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4366893","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.1.1","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4366893","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-4DZyY6LkkKJ31d4mbL0g0sKy+opQRha34apkH2lEDWcxcsjv6HtYztVD34qddZW2DW3ivHTy8LnuEJ+Z2HPlQA==","shasum":"37c8446aad6ca8ace39fffa2f8cb76ce61cc103c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4366893.tgz","fileCount":187,"unpackedSize":2453229,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfrpnxCRA9TVsSAnZWagAAxVEP/A/aCleg83EyMlb0jYJr\nr2zmBJaAmZqbW0S2LUGe3xWfGHNrdxvD1nsVLZ0PIrIMjkJ7WDF8eq3D5Kdu\nQqkfMpoPN4fxK6yLmEcThSeuEN3mNAK6/E9R7I6t0N0N2qhN7RcpLSMNKXbc\nZBpf9w9j3pGB+DxKkhxdr4SE7inxSFZjcfgXU9CzJzvioS+qqSunVu0Tmdk5\nJSH6rws3iLJnUSwMj9UbMwOTiasoDgM2vtS0i3sKKWl2CCzSAsXFphpyQnLH\nH3JDXXhSahrfJzAY7GrH1s9Vk0L7J2rdBdBQmNnazql5RuljkXcbv10wPDkA\ne5yidKY/Ig1xbxwWnrtUkvuNbK0DkGs5Em2cHTpUdD3SnHl7eT9SC/WsB6jv\nS9QlTPEn8ZsgjkcU9OD95z9+K5c7io+mYfDzexqg2KQkGvLFq8LZcpPHF5Sq\n+BM1FifDGlUr7xeg43iiJOSTjwP27hVO6wihoT4pYqbzepZs9qqMWKtxoRq/\nxxe3O53fDu18NQV6BH51RVEXrSdYeFIxIWwevzrdq+7ufg2wjc17MBBCx/cP\nhXjJTKfmVEH6YwjPbJfWjSJ+/Kj2ztMyG+lO8DCMKtRuaau0+UvYaORkLf74\nh1IFjhA68AziW4SI8i34kwZlc51/lwZ1IDEZmB+8wlZmHl9j0VBOH5ROVllK\n0bAV\r\n=l6y1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAb7CJd9JGEHvbim1/GDexn/HW2KwQnXzELv3JIz3hhmAiAGs/szujyoSIiD2iUTj3Oa4FVicIajYNjr3P0inTcntw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4366893_1605278192787_0.6952615752748366"},"_hasShrinkwrap":false},"4.0.4383100":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4383100","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4383100","_nodeVersion":"12.19.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-Xa48RDYJXJARPpIv/HOdzfCfqoLZNMi84bsl8NqSVVo7PbOIe/wH1lli+D82iDyePXLOPCgcg5YPP9lwaU14Vg==","shasum":"4698350827f39cf405a688e7f1b267b1aff52e73","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4383100.tgz","fileCount":193,"unpackedSize":2488465,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJftSrECRA9TVsSAnZWagAA2JUP/ihvuV3Pwk9v929apevv\n3Qxmm5pLgD2xsZwsMl66q+FQruOzB5CXlQZ2WNuAhHekkzrB+JOkx4qlvtCJ\nmy8sSJQUaCAg4CR39GYUlKgVpsRBpk6dMgk4eoQpFJ3iIZxWIgx6N1zhb3ki\nTna3xULELVPTMfFzAjX1qYKW6Bny4jzxW2djXRndAS5faHNMzpdsmjF/DzsG\nJWZxHvgz+WhmdUkR5fS1Tp3FS97J9OqNwZ0jaDXrk+qih7/eOhgZdX3iZtvu\nSnH/c24MwpQCkjqZfU3QeegZn/Z8/j4rZUDzNZJ84X4Ot/KUsgTbZz+nuvaL\nhUqw9HFzYtgTpdwUt/lPhDxwDFMiwQqO1pg1f7o2aUp5VoEjaeK3YnE8by5N\nExbO6kPZhsrvfdwIVDnpVxfie95ycC9+Tg242r6SJj/vO4d3dAJJcME0GGFb\nSmB+iejUaayWp8q6+jAwNcjTGzfTkVtUA3cXNkMNKPYQmfyGTR2GkFi5iIRQ\ngrTGNGyozKDiI8wnAWRo5sUMVAV/U2UO8pA/7pH1xrbiT3Xvl4i7VKIVQPMl\nyadJvEQjo4NwbcImZ54X4ARYAMc0R12nOVs1zti9AE+3+G6fr0Zlj/CVS9gx\nX8zBtrmZluTp8nDpOvUk3gFUrrkLV8j9IlheMUd/2eRBI9PwTIFdlFVakx2W\neJsu\r\n=H4LT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH9bLi2tBcBB6UcGT5omuNXRM2P4VGU8WRT/HcbWem51AiBdWZWnzvFXT4jB/oom5yLKh5rpZ2kQw+ILVDSApoW/Iw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4383100_1605708483320_0.0824124401931774"},"_hasShrinkwrap":false},"4.0.4394830":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4394830","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.1.1","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4394830","_nodeVersion":"12.19.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-EMZDyu7FWNyFHunWaMEtli/YFEHMG9Y+ChvogfiK82si+bVYDJw0TIEiPKLJsffkjJIQ7j99ATEQxh+PDOYQbQ==","shasum":"51cb0a8358638b310fe7c20d4600766ddb54e14b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4394830.tgz","fileCount":187,"unpackedSize":2452873,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfu4TKCRA9TVsSAnZWagAATDYP/A/Wzjz9/c2q/adrtpdR\n7joDIabvSoqIAoj6yQHvdTMY2zSVebxE5gK14fh+anoqUf5ZzpLikhIajqU2\n8z2YFNOKDz9cruzN4xN4JJMkey8uQ/CP/vSNlI9VEwDA31K/IQx9aLBgQ4wN\nRXRvp53oo3LKjd/pQAP6zA3mpSilPtqkbD8jjsUOlXUKnsLSg79zVVsQAP4t\ncV5qlziHS58kx+yfvW7F46vDQKHFb4VufJRydTsTwzBYF50w34QMnVe1ydXg\nOTeiBPcsz1A7Ycn1S5NyCyU0juceoSirEBeVsSYrE3Xy9ylRjhQ6HojysKRY\nczaTT9GvESK6xNlT2AEr80Eny7ErQGYcVUxmkRLvqrkucUTht1uuiscwAmHQ\nQJ2K11r5NZ7YvdMALmVL9VkLZXmdsPgzHZ96GnpAuCzIJbnGHUUd+Tgg3ujv\nvJnyKk9gMuK8+usg8nJF18OUDRB8R3jKD2LYJHFQ8FvJuIwvtzDw1Y21QglX\nlWKOQdmA4LRrs3ti1XlnvyZbzTxe+CMLnbob2lMtih7zxG61Gda2CWkWo07q\nm8Ot4o/VgnS8EFNvuTLBlaTPZNHx7wT6gAcK4M5HaNHSXR5eEXofuZfYbFdO\nqqfdh/OQSvVsNlWRAnKNHunkG4JzpvcG+735QjNmxta72era7PIW5vnyYe0P\n0TAv\r\n=FFnz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCH0rpEHUr1/BI/al8r49f5teC9dx/AzC+NIQ723OnMd8CIQDlT9eDHfUSKpv/WvnCF8LryT/cKaIdHvwV0gxQqEylIg=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4394830_1606124745911_0.8175999751171064"},"_hasShrinkwrap":false},"4.0.4396058":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4396058","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.1.1","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4396058","_nodeVersion":"12.19.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-eU7aGNl9w4arFfQx/W0t55sU3wBMNHxK23yq53VKM89qLlzNV61wK28/REoouEuBC7qUXe6Zl9ZJrqGcsEUb8A==","shasum":"2a244d0e0f0cf2490ab9db40498613889582cfdb","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4396058.tgz","fileCount":187,"unpackedSize":2454539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfu6uqCRA9TVsSAnZWagAAo8kQAKQ4hGnlcQKaYPhpg+Hz\n0QighluPKu9hzelsxacNn2oUtowum7brSds0tYd9j0TiJvmaxWpJfF6N6icr\nIpWP6WuZUX1UKK0acnjmUHXzxIlREcg6zYCMGuALsMjKz4dasz8WQnfdC/VR\n4L3MIFqsQhzxRWvtekAoGSHDO38F9aANamkxc+cnJ1Eh6p+0Ift18pXgUkAZ\nc+CgcenFXCnB5KfKx0Ht0QvxHAfNDbfJ7v3o4t3TaDwtYkUByhG+h66bHR+M\nDc/xJv/P4XA2CJYjc//T9PRTTs/Mhry+uq+Nx5mSSd8xKlsrUu4fRfcD/X6n\neXHML/b1Fo8bvRasnxKgdmv98DcPJCNeUAya9ZzvNszcb27tfJmQeZ8xmOvF\nvN9Rha5jzVa9h3DqW43pPBu98JWCJKEOdp0UlYUkt9s8BIag9Ne7Qspq2wfv\nrgGVQ1ec4Fk8i1FsbBDvlgoYEB6UMf1iBPvP/WoT86lsM9oCskXA3KjUKSa8\nofQmDv6lVIPrgeclFoN6jQyIqMF0XTrWFy5Ec2kHKULj84gDSKEv4/xipt5X\nlrdtrRms3TA5+6oclrtQqi2mPHtCGUKd1wMkFT4FBD2iOfOLG/LNISjRJMvd\nwmGpa9x199/P5AsBWyZh1ol/i4H1P81wv1rnze5EIyal9N4KB4VlWx2+A1uI\nUeSZ\r\n=+uA8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICtELZV64Vsqen9OKkCrkGULIa5UdLEf9pbpac/8FBHKAiA8n5fBlAZ6/6yTLwYciKQnXGF6XrZngY++LOlugEho3Q=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4396058_1606134698149_0.31289072430679354"},"_hasShrinkwrap":false},"4.0.4396062":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4396062","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.1.1","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4396062","_nodeVersion":"12.19.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-SbprPihP27bJY6aXpH0ii4tX7xd4hTsosDbZdsJVgquvlJwY4ckSBNgcvXnH0uCEVO5NRoPAvL08ndXc6od8rA==","shasum":"cf64e709d4793717d28f47420e594be8c58b2446","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4396062.tgz","fileCount":187,"unpackedSize":2454539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfu6vlCRA9TVsSAnZWagAAMa4P/R+XJXEZvknHuOQlTnoN\nwN+IqxTX4JyeXXZUL/xgP2Oy/auaBTQYmzFfUbR2w7aM8jHRm3T0EMwpRPWI\nrxrD7rtKBwVERd4F3KbbBMO0xdIfPiL+H+V7UJMiz0d2HmQCSzDJT1RliJpX\nSrMLczgGN4fWkUDI3MgJgw7YadCbxXMXVi4tuixtzylIbGhL18lIYy9WaY+P\naYpq0owL/bateMUh3hGTzZz2sJ9lMUn1YNpoMgt1PCbN3kf/MrsJ+BY1jiaK\nNZ/l00z62NS04fk7F0aFqaFjnMc72KhBz4S8U3xXDpsxRMK2iAnzwIepCChP\n1WawQsRTzMJpwtX+ktan8ME3ArUj+thX0UNqaHFyPTpxOm1+CSP7al76GFVv\n6y4W1bOzhOe9Cx69mi9QWzbJoyXTOl8yWZ6NiFio58Nh5b7013ZbYWCjuAN6\nHHYr7xIvHSiCzpn6RlEz/bwulNmMEQ1Y+ilrPuC4AEEp+1erP5+ItKWIMlKW\nqvhQSIZsMUJ+Oy/5Yc13MfzdLRX+7hKkxK0cDB6GmtD4nKc0dx5MwbY7tRtc\ndYRODQjMzkbpOVLCLfoxHgRRz+l0jjkP9AF+DF0lKCFNsyxQ+KLL5qGfowpC\n1in5ILH0fiC/w/gw+sLr19nF2xC88weukUvYjOyH6NGga5Z66jTlY4Q3EEWt\n5xVT\r\n=CYuQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFkYt+OK7McosSXhYSBbOGIM6l31ElJsXSVkhBWdUY7KAiBArglfecIErgT9Fic+3mMaP6IsT1VmmLSZR6FMyiR3rA=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4396062_1606134756641_0.2631263408894846"},"_hasShrinkwrap":false},"4.0.4433300":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4433300","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4433300","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-JlULQvS+4MlF11g0NyM8qoTlheNngbJUu7Evp5UsRTEzGo4HmNT9ZFMIUyk+mWKiVMFO6ZdY3yoawTk1to9CNg==","shasum":"72d80c2b97d5fe1940ba286327b8f21ef2e83812","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4433300.tgz","fileCount":199,"unpackedSize":2658151,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfxRJICRA9TVsSAnZWagAAcdsP/jLvC2adCw0ferBZKxgO\n1pa3yqPE013qnzARi7kD3FmPOTJgHARIAka9Y0RyasGopeS0TTCeanl6pVas\nD+YMw21BLvfCOiray2KpyV3nqZJTZPOohhpKrQgDdEhveQuDdofV6VoMxoPH\nQNo9lIgLmSAVlVD+4/++H4S1FD715+2XQ3OojBVnUeLF5M/5e84Fyf5d9PnS\nvjpPvALSYSztQZ2/SVSnVUAUREK1HOzeTSjy/UIfZ4YLreyNiTMhp/EoL/XP\nz0pYTA6dQRB2ov/NiiVcYOtN2eR9+0DxerjLmUutAXN5PGVH4t9LCgHTvcYg\n/RKIH+949WoHJmYI2xqdhNomJbFlOeFtCsHxrrm+E5OD+DutfI0ysFnnWcjn\nMTpqOg8np4txpo1OqamENTZwdh2YWyt1mUxfYSrLDuTSkw4FwJT5aEl7NYwm\nG8PVfxIKwOsgyY7do+VeGFWExCGvC2YKJsuwxvvRmxOeyKcOEkL1WvjcmS4l\nUZEuhX9p6C5SsD5lRJl7kBY9EMjH7v+te3mZsfnBUby4s2D6ZOzTUDudOfW+\nejagwRhETTwl/MgHhfd1rvJev4sMr3Myv3VxaLuyWBxlrWuDaW09x1hryYFm\nWkrBHTWlaUxdK/zkxMA5ZTpbsSCET5M2PNyDC2B8qv6d9JT8tI6xK9rGqV9Q\nfhFY\r\n=z+S1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCwgkb3EwnFlM4FvmQnzsrcdn23YbYlaRqwPyRnTNF7zAIgRSYP8CCcK+dRbcl6rb8zDX79kmyQAVbSKwGXnf9XDgE="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4433300_1606750790995_0.8501798464258439"},"_hasShrinkwrap":false},"4.0.4438332":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4438332","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4438332","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-aCzumfvXnB1RNfvbZauqS6OQlRozXZ45tuvHQ+au/ZXpvKjbmKFHEyJe7OT2gGXExHQaSSllf8y6d1QIf7x87A==","shasum":"222858471beaef23f25adfac3d5bf7a694c56b91","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4438332.tgz","fileCount":199,"unpackedSize":2658766,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfxl4+CRA9TVsSAnZWagAA9yMP/Rc9eso1f7/fA6d5gEro\ntQMk+KlnhUMoEnkbR6QXqO1Dzihv3Xc6ntUnc+oxzNwRFZxQsyWsg2C7PPoP\nODUA9q06xu8GD0CXYNLrAkGnyGH11cEvj3DS1gIcnCCkMbzYSY2YRtS9DLZZ\nDFyHCvmoygNUIlxA4iA3mAlXqFqZI3Qsb2JlcW5+2OY2EmbJ32ibermGsn9d\nkY5dxgIzyJPZL5C1s5mKmRqiWa4Oe0lgYFuY1W8DLs7YOLO4EXJB/ETBX5r7\ntJEHinIlEFgiJHVq0SEHGAvmI1g0UKOKRgORhoWNUJa4KnH5uJI1bc/RhlxP\nVQ4cwLizD8DWpMG83scUN/3toZariW3dywstBYFUmFNXA7FvunkDF4x7oJfP\nBep7wW7Vi+YRIC2G5vQBOuRFrpioR9TMu9QQY8ZptwB+5NaqdptJ7XLxs4t7\n4RmbLcaNlUEw5YCZtc65juB6EbEwo2zsAwnobRJGQaRFwFe1mrH/U/jq/Y+u\nNUKY80qArEG/mbJ1gn8SBFqU/TKMXJ/OTTEE1NL1vk4zn19BZ5y/mTePRjq3\nESlXGVQmzdwHrdC/guh6vdDy6FPD6N5O/jcbjndOWWzzde/VEKEkZk+jc4mV\n0sG+1Mvj3J9UWi2wVIi9BDdkHCJfOR9FyIlEKCIKQGkV1Q3fqb7k2JKvCUX7\nbQQG\r\n=ZM+s\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBVpKuxz6D787fbDqDPqBwBuSDx8FAtTPEnzw1NuKTwnAiEA9hZOwYLGlqp1VORCTRhmvHlikFyTu3A0BiQYNvWWfnI="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4438332_1606835773794_0.5989489737885476"},"_hasShrinkwrap":false},"4.0.4438536":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4438536","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4438536","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-5WJKpeTNDJchnXuBh8hGU4ukSZ4P66+3xE0+VDnroqR8ujZ+5znNHCDHo4FXx9SUS+/vXNSn7GeRLicWbHUs3Q==","shasum":"08334f414732068837a86350f8fc12494ffe938a","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4438536.tgz","fileCount":199,"unpackedSize":2660429,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfxmAQCRA9TVsSAnZWagAA2SkP/3tbHV21Tyg+eA+GIaJU\n0btwrxeus+fWrn1DOqvBygkNoNvDKNraH5TqsfKMA5zpGxLwL6sckI/HDmgj\nFW7ToPXPgx4CBZnygRAi4NZ6i6M0Zd0JfzCIDRcRY5Z9cdPy8t3AnesdfEPL\nJBcUkP2lHbckiBLipBCwF2JWUT+RLXvzjYV92hpguNLRk5cCqihFCw21KJU/\nv9Cl7Vrf4gXE2C5YNjW3PgqQCMm6EoO/Cpf8ae4/29lo2lLAZYl6vq1aG7Yb\nnPgCpT7ih1FLfN37A3x6erP2SiR3uqzX68pDiXCP+zZwojgvh6n80xEqz2g9\nuVeMRtPR6b3+UA699nChrsny8qqz3pXmh8hQz+OMAtdypXJNhuixRFZjNjoD\nHiccv6URHPCIKRFWXph0j9NG7EPSq3sHQPp8VItLKMXnp19cr91FdSJY0uTJ\nGq7NmRPGZ6ITyY/+Z65IY9SyIA90DbjfTXnUUL64hwDYI+b3IgIhh4PV7px7\ncv6oWX5dA5suDp1OK3VnR2swTqibvSDGOIpp0TQ6ClNTZy0S/oHizfbxVlVY\ngQ/W00lzEOhpjHn1E4d6vGi7yXZxrTsL4pyhKUMosd/6E3gJ6HD2TQp+csil\nosqYanVl8Yc0/jfNaxJ9x/bsGCTPmKw23yL8VOGJYOKGhjbl7KKOA71gLm4S\nKSvi\r\n=fFnO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCTNq1LsEgsoOlzzl7TZGkaIlYF4J3W7SjLkRDUDKddPwIhANjo8UJ9AF05IYFUkF+GR4bBJbuM7Urc6rQyY8lSF4Kg"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4438536_1606836239798_0.9750876207758958"},"_hasShrinkwrap":false},"4.0.4438881":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4438881","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4438881","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-jmnYiLHUHtCrUOBYjGcz3hym+waMNyPpcapaMYw+tIN/Ac0+QpUWNx01ez8Esq+JpDxQIukpIAoNanWTyl8wVw==","shasum":"876f6499d44fca94c4aae34736f7c5d2b2f3f3ce","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4438881.tgz","fileCount":199,"unpackedSize":2660461,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfxnqZCRA9TVsSAnZWagAAleMP/j/WR87eECROzGHjZ5wb\nheu+JeePeI81bdfYfpgeL67+bkH+7GB2rj9T5ACj/N5WTgcV0arIqwCn4k7Q\nsWChWBycU5SXJNqdK9TsMhcPRfXW97QygggDs0zO5b/xKDnOkBHHYbPdlbSy\nfEW5zQJY4ijXubRoWcAWIVwFLf6JeH7TR4Qn7tECWVzCxhWnxYLC7EIiWtOv\nGkhZPRDnMJ29EZky2TRPyFS/HNEgjmi1uwv/Hjs2H86IiUnfFREJs19I4Rg5\n2W5w9VYTPc154tScbEYcz412TymbAvR1UxDVdI/Rk9OtH7UZoZXREeYJP+uE\nTRAafzS9S3xgaBy9rAhQICE60EKjR3mhCO7LbNonwArvqqhI+8m7OKnMnPoY\nKE4828FT6CY95DsXo9JstwrfBCOJ2I1c8xKLOw2x9CWcPtRRmVkFwx7xKeQ+\nALbZOt4nr5hf6kZf10QISJr8aaW6B4OypEAH+eLou2t2in7s0hFjJrBYOfK9\nxdJAcGmG4ZdsMG+ELNAi86QasAbwEy6MvjV42EyIqQWe+efKbAkuwZb4ez1v\nDiCem6cmHmE7WUfs48ysy+ymNlNFyoS1LWgAzowlztGmtsZi/jOOjZaXNGst\ntzURzyAezPouGDIDDPTDh0fpLMdbiDzYfWHuZ4/ZOCCdzqwkpbQjo8DV7M60\neORk\r\n=8ASb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAUPTxJ9juRv5iB87QqDjNZ82kq8gOSRpbzuxJroq6BnAiAZmSJgqOpHlIonpSgQBOuToYtoZAsCqh+LL0qzOUhz6Q=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4438881_1606843033085_0.5619077889936523"},"_hasShrinkwrap":false},"4.0.4456258":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4456258","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4456258","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-7MsN88YHMdtQZj10HUVXA861ngsnJOqGInFefCVnimlrnGVSxHnOu4e7ifCNVU/wHPEiOR76pm7nDohDI0YQ+A==","shasum":"6220b5408a99f3579649bb71f2526336feee8bb4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4456258.tgz","fileCount":199,"unpackedSize":2661307,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfymiUCRA9TVsSAnZWagAAB4oP/3W5CPp50xaif/S9Pw0z\nzZqSZLH51hdGzCwkiTHbTnVgBBzTyqNinIMOvsOJlgamnfvoPa+qUPdU2Qol\nja1doKRvE+cRv2dXUgEsjvgGkJs4g62CEwRHI9FjZQLXkyiAiiR6c3z601dV\nm52aPp2aCRTac9QCdQfnmj1nmS+9kbyFw6Cu0iJpy9hvp8xKH3l2w5VNvqmC\nNw1IfLw8ITJHtqR+Hisff2beJPnNkByYNgqtGIaAyE9EkIzEHAwD7lIvzmui\ncEQYlLWwPx3aiiEiDAqzaIY77stzBofe/3da/I82kpl+kW8jfplVi5CNZa1X\nFvY8lr6sllpG2/P7Fi+CQqmr5XaQGKDoeZBUrKd0nmx8AiXF1BrJYgYaBI1M\nFPD6o9ojp84nh6eVFzuaYoroUuQOc38C656xdYNeoqdKQdMfNkE8fhBAUVtG\nrapVVsmGWd3PJxbpePCLHaNX+r/fAQD8YnCA80Ma2PC2T9oWD9O/ppmo7S5L\nlLHntasDyePIHpLSRjl+SBfLizDfAla2WLPrKBc4bvlPkaZl2f3KOBXVZppB\nMhr5VW0IBBvjxDJNu+tQE0M68d9yQSQeYRU+sTgy0Fbk/B80905a9pbHToVB\nkG58NJ4h5z4Ju7Eu3D/fijEWMCVVf8CZ22Ct/Z56x+RBWMzlKYGdN28h0daf\nJO7n\r\n=GvTJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAscwObUnBuYyS3P9/tgKRAivvwTnUfIonYtdfDiIWGsAiEAmuqd/zocEOMt8bY5dFTs/EnVM3sK8YJzuDg15tK2+Yo="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4456258_1607100563309_0.7177210851280136"},"_hasShrinkwrap":false},"4.0.4456738":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4456738","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4456738","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-5Q+MXfEQkmQX5PlR5fgpUflpNAtf/7zVTQ+KkZ3WlFjv6rp1AE1DE8364FyncfSaxVnbYm6qFSXruCfk1Tgpkg==","shasum":"7fd2f3fe2ae4fb18f839da8a13ab64cbf8405a8f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4456738.tgz","fileCount":199,"unpackedSize":2662112,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfynK4CRA9TVsSAnZWagAAVzQP/37OJYoi2s7eEMR0Yc7m\nCsmLe8lluhCY1aK+qapcF9PyZeoPNqmTKQ/gkZ1DzgWfYkL33TYts8Sms0d1\nTMJVTuft1D+4jqx8N1br6z9DvcCI+FXNbJ8cOMIEHJPyiyFw1m9ji2diZtyV\nJgLHCATzgBM2aLk1VvM8L/O+fMg4FXUYHlm7+nMJFu4/X/pCqI5EGcVe1WXF\nBiH+TZEY0oT3tyrQ9ma5GXeJnziikSsdCVQl8pb6L60DKfl8rNLj5hO5flQO\nOrTO30gtQblYTHmt1/fEO0zC4vUnwKY7wu++UfLpoqNk/Fw7LTujMR/IpNoP\nuGdiHcg23ltlTsPXRQZ8MZnaZe0KtAzode/uz1i302U3+V7B/ibH0rEpcEnn\nfpsRPx1TYpliTi1uL70PqBywBuwaJd2Whw6EujUewkt1Jvxpd6HabAIq/v1c\nzw3ctEj8uw0KdNbG0LY3trr8OH6hnIh/XXcM3Bjwxym9kN2oRq7WMQ6PgkME\njcBpDoodIs6JCP7Smdooin7bEJtauHAuzKKQE35wW31iu2JGfwP6KxZS+Ihb\nElkVCgz9HJVMsKQXLHv+I3oI8TGW1uGKddDaCyGdUsJBiPrz1PSxiAg5cmnk\ncuL5oZNS/i7I7i72EwFePtY6TqTXgELOFNfaavo6ybfHtl3S+dIbzjfijDHx\nyzMh\r\n=79SX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBaC+V5s8vBz9mqqb1m6Ygtoxwodqe/DCHQtA7rEWoT+AiEAj0T4oKrmmgsfobD6mPigdyOcKMdEgluJhdN0pXjTo6g="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4456738_1607103159509_0.10382287118077582"},"_hasShrinkwrap":false},"4.0.4460253":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4460253","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4460253","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-5r4azVQKtbTnMBU8tkN3ZFqIkUJOGGVBFwAx9cjCF8ENv+sZPjgESnFMO5rzrEdtvqnua+5juOdCh7ko1cXEnA==","shasum":"beadd745620408fde2368ca09e799884be12a5b4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4460253.tgz","fileCount":199,"unpackedSize":2665877,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzgXiCRA9TVsSAnZWagAA/xQP/3hM1BY+6sHLy467WGI0\n2Lnt6NVwutvPoKN0up6TRIKC4ctFNLf+KOC1xpkU6W6X6fZLkD0YbLF/F7l+\nzYhE1DIpn2zXvaWOND+Lniul3t8uTRWQdRIJo1HBLP7WyM1vsv4C10Xj0Mdj\njuLYJXz4PQr5GjHdChdKMmKL7k/1G1aMDs7PiKAAzyuoKyPulfArj6IF//DD\nuxqTvwxZt+2K9QiXJAmHZ5E2GsIbG1JX/vqX6uL8Z5eUveYOHiZ21J/EAyxo\nBgIToIZ3VqfG6vy92En0TRP3oeshYkbenWYOYXWCqK07umq4A4LVcj5OH1IR\n6mTpMLQ3XspaA/Ks8MCOrGL05i6tu59514uVVzNsK+QeMlTwgAzpWJMlCXT3\nSUr5R+uC8C9FgTzuFcqjwGdwN11J5DyvVHuMMEx5YHH7GczmvxqEwJ8z7nQb\n+MN0z0bT8LhSO693/Uuni5iHbtc4HMvIu3UrD/OhHf4j87CTpsK+GT+vtRrX\nXTf76XJaKxTWCAaa2GoxhKOYFI3I4e8VLPfRK0/jAk5Wys34HyKtThZLDA75\neL/ebkC5jepZyCQB2r5MfbS6H0yoPbCvel8ouj7STj4Sfga0LodtCm9bmhfq\nnCEGaxSKBJkGDpH1R+QWPs8t2ylHW6pap8m62uDouilRSLA6retJ1oedJBeD\nG1VV\r\n=s4VY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCdiUz9J8ijymj6d0/zQaDFdcpVMg9ofZADk4Iq0ODjewIgdZ+Sw6msV5TVmcvrCOrkZZHyQ+0vf/7QxzluGVfT+Eg="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4460253_1607337442016_0.7722643847472299"},"_hasShrinkwrap":false},"4.0.4466780":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4466780","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4466780","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-QafGRcZP9im6scMseWjk0fN7EskSmV75kRphMdka1YXgxc2y70WIyN5orELYekY05w6XmrK7/69wRVg4M4WXQw==","shasum":"91c8d26308e026db362c4cc2ac646a5af9f3e712","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4466780.tgz","fileCount":199,"unpackedSize":2734121,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfz6EsCRA9TVsSAnZWagAAj0oP/0xXAokC5ID+fvaefbZ1\n1Ocd3Zy0IEaEPERMJ4jb1L5X+M0q2uC5TdYc082gJG5g44xbbWafZFwoqmdQ\ncg+Q1Cbk08rEGfPD7QQSUtulW7ckMbXZ77pwZQcA/aPpEHrn+gO1YbOD0/L8\nxTFQk8/gfU0E1nMVPZkYmDPScQgz8CKu4RUcwUM7O/5q7QvfE4bm0x7kDw7u\nJxPSkXBSVpO7VMZOR0Flq0HRcuolQp/DDJzoWGqWaHQB2/oyOL9MiIoSIWmO\nkIxOpSorjXtDSZdJ3vzLjoVkXQT3JoAPjK+YJ2hB6PhglVUElf+SDh5OPF9F\nv0jh2LAS9+F+DbrdTuqfbHJod+3oe9umOhtIvMX9Aa7hu+eHKvaqH9BWcHRb\nbxLY3wpa/WwsMR5HGqFfPmCXY1Mm7FqMHPJTjRZejfGkBIMgPt6PMQ2x5ohp\nEDST7ufMoYwQ9T2DDCFoJFFmE3RkaoGrUdRmzKJpMqCmZ3bScncPqRpv80d1\nT/Sktle0OiJJ9v5MNjWXy95N1RU3cBWkZ2AvmR7+ALxbC7WsnP/+h9rwyjS7\nWn+Af0+68Rkx8Nea/zTgec3Cj1HVbsa5SxlYUs++rBd6+hUBFWWnw2peEqYm\nDHvXF0d077LaxYlzjOk4HwW7nJRMpjwZtp1qha2a6dcBmxGbvLAiVhOdDMRS\n8Jhl\r\n=yxXF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDwuHRUur7kPhf91eBmjwddNsX3RW/V2OjvAbI36sKzcAIhAKMC79sNHvM53wqH4Pf88WR7Qmd5V+XDOOzOR7HQjj1U"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4466780_1607442732304_0.10370281327607755"},"_hasShrinkwrap":false},"4.0.4467680":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4467680","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4467680","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-zMxGzXm3+oa/tLR4EqvhviMjy9YZa3+QvFOvxaMWj5fUbw+4Yo8T0ttr1TfebxwQcyTxei5Tpt2VpZM0QrM+OA==","shasum":"4b3d3ed9eda92ed11b40ac2e2bac2eb7d3f3ff5f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4467680.tgz","fileCount":199,"unpackedSize":2734211,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfz7W7CRA9TVsSAnZWagAA67MP/2HJoUPI6ZBRCZirdtz6\nxIXeNvlkUXGeRjUbd0C2ta+Da7P2p5pqA5Wil5u0zzqtQf2IdHxCrrVUkLzk\nQ32Jnyoh7IShCtFqlT0hk/uK+G064szSmHPWTNSYAxEYRhOX/aWFOSEsODQk\nVUvEI7l0ifo4RTJmcx5zyK3TEDWMKq+J7gn1Pf0ooO7nkwmMm9sDnRK4n37g\nP/8NUhf7ajsg8nR3H0rUPjgwctpryCdujiCX7Tl2sgSZCXXAGmWxSvZfqzwX\nPhqdgFRnQAxrJPZG+81+Q1S+lvHtg6JxzQWUkqY72hkKWN62zMsg2leHJ4Zf\nbjSLVWLYodx3/5yNYLs20EiGKLjfFZDXnZZcwZglGkjd/i7hIOYVlWsVjtXY\n32KJuG2FGa1mBC9g3ZDwdULoySV7iva7JI6/FwXLBL08JdhQ1qt4e/H9LkJg\naaRCDp88akuEU+yhhuqjK4d27tYZreVuQixRJ/ZwawGE71a34ktep+HRNaJG\n9kdZjpXcDf2avaRoNVdtl6pF2oK415dwvhfgz9qpbnBZG9gnTJVfNlzFDhRB\n1V8Yodcx+tP5mOHt8e6Z243gNfOY9FHdDktbXOUy5xGEiCSDAwYZjBXIQIbV\n/897X3ZEY4Emwbs7ysumMxDYPQvC4S8mZ9xoG+T5/HiALOSqtVLaocu1EKZq\nU2oy\r\n=KtHM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEjgAz+lRF+6LJj3iWw0uHPigVxHiNLq24v7jP24mTIRAiBC6XDkJ3mD7GrT3FDDwn482v78PRjNlhbVAhSXQkJLaQ=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4467680_1607447995301_0.0337312800015237"},"_hasShrinkwrap":false},"4.0.4467990":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4467990","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4467990","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-nXaxd7kWcKWwy2QJpRaxWc6NA34TvD3K2cFdH6LZhLZ1OaOTzw8yAAB3rXVa97hgzmxfPKrlIP9s6PiYS49f3A==","shasum":"21a0e01c41b38e637e8c224e0f56642c0961cdf8","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4467990.tgz","fileCount":199,"unpackedSize":2735084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfz7v1CRA9TVsSAnZWagAANLoP/08eSsjKClXH1gMmaAd3\nPJGNF7VDDvZuLRDoKxaIPGzVviceOV5ZrQc7PDtOK07R4PVlsTX8GxLXEse8\njHO+Rh9Z18aZSokpj1jQKl02EdN5TC8kXKYWEj678tiKQV4LtSclUshmwXIQ\ngQSKYqnXXCrmf5Qhdd2oT3k0+5SBcKZtTvC+/9cWnaTSoO73sAicqsh5pqUT\nQntPY11eH1hgliqlYYsA6vQ3LUikmZyKLh5HydWYJU+otIzNB9XP8dauh7Eo\nTWj3qFOWwJ6mbLR9BEaCmKn+ukNWgHgX3tkuQgfIZ+uL8t7aiSQtZecxirFz\ndAMbyMBZhy2GdNChIU1uxir70v+BQfx5qqW1tp8mLgshIjuobr5tiC8XE3TL\n1bsp3uTIDrKSsNzuoK6x6LBX5PWu2SaIuwO1JRYwu270a2jgzQyWVXIZEWkb\n8vlqGJnxbkFC6SSKignef7WPQTEJ8HV0q0iePkW8CtEbmgoKplrNK4UrG6iZ\nsr4FNBwNe1at1wAgc0Jnu07wGkIaKZMFLtVucP46EOfTh/WJILSLl/h+DnAK\nZZI4LZQXe7ybTf8vwOh1EcAHhG36OyWzSagqW8NzQ1SKGfCuguHU7HUlFuIT\ncMMXHyuEjXTb0mWav/o5rFfQtH1Uv25PnK3311yCDe7ENxmGLN+VvNR8y5qi\nQqPA\r\n=7FIE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDdFjVwuk8MniOAZhIjycWnuVyidqDJqUg8Wau7gqlHywIgGYiHvsHd49baEtZyN40OGcsUdxuWtIis4du6ctwPAB4="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4467990_1607449589008_0.3497389130280484"},"_hasShrinkwrap":false},"4.0.4481265":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4481265","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4481265","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-YKQhKeuG1uR9Xo49AW9sQXMjE0p4DkmvNqw3n+W7PdBE74Ue0v/bzcuvNf+kSQxdtzGlI6RT81AmSfDS7RrPnQ==","shasum":"df2cdca49a549f343550bdd8f266503d683fbf2b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4481265.tgz","fileCount":199,"unpackedSize":2735630,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0mTJCRA9TVsSAnZWagAARtYP/irUzTgHmInF93qXZz1j\nXkxvKCco5oyLZE542aHbBICvkfqTNsklcBax0wXyElXr/PBNe40qsQFf1pWC\nepBilpRswQwEp9z/dJ+np8DSPE59UuR6liagzeXHJQo4FMD1dLtvXExi9aGF\nHTJvvjoUOC7+AW077futRelgx2he/xPCeSe657OadPKuxWipeJLrrUQx1zIY\nGHyFQO2V3zIfQPsQZdMVIXSpYEl+EmG2IiEZBwwwlLlSqZuZD5U268lZBM/b\n60zMbRquYs28GcGsANGEslnYXtwo1KrNwpTI/ibBaJTXh1BeBh1tBP+HHLTN\nekpHb2W7UjaLLgfuuObkeqPBlym2ruz8ywpzkYZLe+U9Vm3YPI/FjSy9/sJ0\ng0SkItxQ9NnhPLCy98bSBSk6vDPTI1cwILottZ7CUa86iK2qthMn6J9FgCbr\no/WsdNnVvSUQ4TtKWD+qQPM7eyydFsQFQgq9FUsAWa8fX/vLmK3Y2pxozfH8\nIdCLDjWdxOHfG+Cr/mYah1n4Q49WxsyvesavqLKRG1r0vy8I8ulqa5MWvPPb\n+BdCL8bcLHhjMmbrhcDGDKzSBHEyCjZJSFHtoJEW3HhTnnNGzjIa8/7q0zJt\neopPMk5qh8zPQLkv2QBrR3BGbb87rVR4++aRpw05MhjKb6p9FSDEF9jVt90m\n1dA8\r\n=5e48\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD//nLS1+YCSSSPZHLgYMv45teBXzir5So3Dexrzs2uYgIhAMkRMZ/tTW30q+WiHYoodwSefMGt7n4gpFHlmMnEfkhA"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4481265_1607623880592_0.46499055496591835"},"_hasShrinkwrap":false},"4.0.4486532":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4486532","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4486532","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-sq7pIrlExCoRvL7iBJ9Qiup7YMkFnzWJ/JD6PPHSx3OCMQL5kUPJ7PA6CH/PQupSCCG6hCto8YHVWgE/qplrmg==","shasum":"3f25f2ffb10416fe493a533058ebf70f92e4fde8","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4486532.tgz","fileCount":199,"unpackedSize":2735486,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf06VGCRA9TVsSAnZWagAAa+kQAJNj6hf8Pv8TNl3u1aKu\n7KirLoDm/vnAVlu0ksCnVnws598JglW1ETk23NaFar+w1wt+cXdl4OJjDUVj\nx9zhe/VdRY2rKkgpsyTdTPq2IRZsuuYdwLPx1zhmGOspMxBmyaVDYNALYZeo\nVlMuqBw0je/aVZ0wx2LOyNwNchln7jaqBmBsKbzg1QJNYgECeKgvpouHdGCu\n+I4MBKRN7w+l6cvdi/9ebGi+B6xq2ZZjCSbSBK8lgUGjgmNmRdH94vGg6yd3\niPXb9frR5ZGhQu1ijTgE8iA8BSm5OvPbTnKSzGo316m3nH5yTdanKpg4uajM\nDCdYEg1YPzQQFCfKHdSZbcE01MfQ+UsgahvbK99PEiMCexIei1cMN7/CFm5K\necVFjNusN7IMwCXz49q1UfUsGr3D2anFK3ZSEtmmeZjv7keBcTsPoMiSaffR\nYeTx65e8P2nb+EINaBMczen8uYKWqbjnBM5b/VpMcg/iH52o0zS2DASh1AEt\nLfk94JrLdQofgovAB00bb28Kl2lV8LJlnmoZc1PTwoR4+d8z1vGwHOE4oboD\nbsOayI+FcsXBeu3wnL9OOJzQ6xJpS7TPeL09Hs17jsqF72+MILIu7EmtFF0p\nvNHX+jIuCHP6nhGH3ycI2XhOvbLo6V7lMiVkDI6w+U0Uwry16mZ8QhQIeKGS\nfDcQ\r\n=2Pph\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC7kXLS5Hyl//CsAAQmJO3GnWwwoZrl77nlDDK7RuzizQIgfOdbcJJOKC8JgRuSiVgwPpdu9m5n1DqWPa8nD2zu7ig="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"mcbot","email":"roger.pettett@metrichor.com"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4486532_1607705926080_0.08577165851142943"},"_hasShrinkwrap":false},"4.0.4491868":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4491868","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4491868","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-yzHJRQnR0u4DxhPal4MfVY/YtJFDAjtBFR3jC64V3VLkFtp2MBRe7cqB6ecu/x8LPQG3UU6Obkj1nMhoQx5VQg==","shasum":"74db54bda49aac2d77a7712c7fc08b3508ae7c1c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4491868.tgz","fileCount":199,"unpackedSize":2735185,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf14HNCRA9TVsSAnZWagAAvj0P/RtURYSOfyEK96g0+zJF\n2GjEDx2dq2Jbz44kxLZjknQTl+EOxaEZ333177yJlkxUVDArdcXSSOUc/khY\nCy2rHo2tapK1+Q16OdOJX/XMNY2FSojSqVMmizD/E2NRgZzk0zEJkYV4Ta/d\nUxvOnNwQIc9xcVB8EE0QotahfNMJifrn8Len0rslnBnGdeKR5uvvD/0da5sM\nwezzQQu/LAULhUE12ilCvAn/M86YekAhWoyefzINoykZHXnYYWVwCBgb1NQX\nWwQxInlERfPvlhIo6PxoCeUY9fSGJLnSSc+DB9b/v6ci3N4eZHctxoLC4YA/\neMGEYoO3lI5QOzhhDPoafeRzfuxMNGoFXGpg0Z2cD3DMLcgyRpD7cY0GRGF0\nK23KtuHlPGBVOAEMW5G1+PZCqL9Ku5VmGtA9t8OWifOzaNbZ05vq1j+eEgbk\nBMo/VFXDGm5Rf2R9Avvh7rv0AbMPHRDsh88xAVTG0+1VN3N/3bfNavSCWp0g\ndhM7WnXc4aWOeDNwiK4JNL74bp3DzepH7SYNwzH4lJsb2Q+n1DPAEGpyFhTo\nB91Do66aeCes5g0Mp7TQpbYiPJrHp6A6SMX8jFlJFN4sDYJHsctvDieNWD5g\nDwtqk5/GexxUK8FHzIHrWHEe3uwZRQDuvyVuTrvBbxjQ3RMxOOMumZHlHTLE\nVSqc\r\n=6asN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCQ+XP5gJArNSsaoauxSeMGFyCa1YbukT3g50Yx5YNVXAIhAPR2yFWAQ/x9kzPxnVGNKk/wO6f3bORs+hQXh90fgTDQ"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4491868_1607958989257_0.9217530988602864"},"_hasShrinkwrap":false},"4.0.4492416":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4492416","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4492416","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-4jxTYcT4zvqUFCiV5yL2XhkFvXTUV2vs0aT2MbQtB063buoCKu93Dd4HE0hFQ2Szz3TvwocMbLKp7MreirbPwQ==","shasum":"2188ae767330d80f6e501027be319219809cdb8a","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4492416.tgz","fileCount":199,"unpackedSize":2735292,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf14YxCRA9TVsSAnZWagAAntsP/RXiSuwmSdoLpI4zDsQy\nh5OV3qbhA/lxWw9A5bDfe9/yLtRqT2DgeLdptuHR8dqzuBLs4GUx1HSodDZM\nr6BnQxSvcrUcivXuQI4PUhfCXS2QZn7NtpyJWdaUfA+5yXZ12poDXHpY08h0\n1BM84KiGGOOFgriCTUuXHY9tG19kqS/nOo04Mzq86U/vlRMWB8c0JF2ZCN4t\nnHa9hUNHf6hi20raPHpdoMX0frbv0Ne9hslboLYX/3WdHjVuLBpyyRW3qi+6\nvHdebl+jO0D/fvDg4ZIm54XZ6GMyrtIPQO49pjMG7faFUuRH4WksG1TpnFNs\nNWDaCWcJabOtnk/1BSg2Uu5ubmJoozcCrJunDyyugpU8ohgv51OEo/v5Ag/E\nTEER52IzYJy+6oOPdBJiDmyRNYOSCRMVHMxRKoFaAzvwxOCwpWz6aUYr0Mdt\nE0y+/OqbTY+dBheladyeRMPPAAaFqhoxfdwPvqBNpsRUKafO89AwBq5GsS3j\nhqOkGwqUFkc50o0krPayOu4LaZjzWHeJ6TnP89kZI58FY7L+t48Gsau3RNYh\nHPzoi96un0y1MQLbtQYrvDlYzkKXEkxJjnK/0t1NN7s8NYKcn3flocm6yf6Y\nrjfmxb2j3GWjRt81ifGxDih07YGViURC9JkuCl8B1Y8Zk4bQtc4cU/nckSet\n8B2L\r\n=qgtI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHFrGA8ml5g0eym8fWePt1VOXzVWnPt/zyyzKsnv5zwzAiB6NlMnhdt35Lp532kUCpDVJwN1LEoOBA8TATk4NGCgxA=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4492416_1607960109486_0.06676936549781343"},"_hasShrinkwrap":false},"4.0.4492990":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4492990","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4492990","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-2Fq5hDcAVFu49ds9dnKi6ABsZYA4SpDyOJTRvjhUVWMIhJwDl9loA+YHSJwkhuCWOFrNca3ob4kX3kNMhwuo6w==","shasum":"83a50110fd99d2089b42df31a977536997606d0e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4492990.tgz","fileCount":199,"unpackedSize":2735292,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf15jMCRA9TVsSAnZWagAATs0P/2eEbA8wB6Hw6BXYeE+r\nV6StCEop99VcUmNi/aole7uG3yLBTfWPM2+91I3P2z0dhTw97TOKwvkF6pA/\nvdJQm0LzoFqtIEH18FodCyn1igPy78y7KolkvASsLvBmAkcTnCHtYBZDxsp4\nnnbMCUJwdDRds5Zv92+kJ2vyBPJxUtb8KY3xf7qjzW0/94bAm8ktalC9C7I+\nGvn4M07Frm1LUlvw8bLfgKYVUq58OD+bAltiwq9dZiPwbpBEtiTL9rQjlXaN\na7hRhGFlnc6yo9CMEXBOIUV0K1FAQZ3t3KQbLiSJvg94otmjZwWnZhBVlKJ3\nB2P6fjCreQIudvN7+9Zb8MNihwzjSKlL7azcwUBSsLfZ3Tm3XovV+AeTHxAo\nc0kOmWn3WL9InYjXaTjLPKwHkFOvcIkfDWbx2KRB3ZTuDB+XciBqwAu7W7Ze\nhmBlQS2iUNJP/N/5/2M3xZzFae2XEOXdkYGyJoNmf74QYvkHiJG1aWUVhxMe\nQTjIWpUvF9N+JCnL9P7FtIHitC4II4q27tK8oXdtPeODQhiPN4FPO3YdqLq/\nfVH1YKVj6WmVDoWuWcnvJz0LUxR5LFIrFklVrojk3fG7/FWzRV7orDklGzvm\nDdZou6wvOPmPFecz7252cvLxcZtad+9VzmtW0CkhP/0B+zwP9c21yW/fz3S1\nai+o\r\n=I/cz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDrXn5BBY5PHgEPt4qnHb9dXFHXe9pFyzDBDpmP/Otm0gIgHRYJpOoDp0vBM+vsIaSlCOd2lDnuVNBBlsw2cIUpzCE="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4492990_1607964875632_0.14981156360305237"},"_hasShrinkwrap":false},"4.0.4564472":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4564472","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4564472","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-5T78padJEADWSL67FtxSbvYOLEHSDEAopYBhOnDj/lKCRxOsNQBb1DjYqtJt5kC2mFpstJV2YtIzq6YCEr/AfA==","shasum":"a0e9a8400df902ff0a414218cae1de6e9bc1aa81","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4564472.tgz","fileCount":199,"unpackedSize":2735973,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf9HBiCRA9TVsSAnZWagAAd4cQAJWkf/sqGIIW74z98eY+\nYtmeHH3Kjr/3N2kicYnTutrV6zVPHEvLeBlwRJQSrgfqfJB8Eqn2Vsh9MBW4\nggna7SqwA+8QSYR5EVmds7yVAdnCt0XmTCgt4y7MbEdrcPAc1F/jaavZbjT4\nKECt9CYjzGbmaT8LfgVyK3yw6tuftNuE4GbgokaqAYZUb86cx9gW0dXJqrdh\nUvLra/cikXc2o+NEJ4UvCy+mx1LZjwkTeKEuAnhLVhkZ/ug+GDgQU+CEttEC\n3tA7dGCrFNnf5XS5gykWI2WPD7psnpLW4q10xls5FYPvy2RijlJD/A8hnYuh\nKH/NrALM5T/ZtPrw8lIv6scgACv5wWJ2AmRmgrnyI4JRqb7QBFBxLH0jl2ri\n3e4yCUyQc6pQdS6zg5a2Vc0PjxYJlAvPEzYYJwOFaBRQvSI9WgMmhi3rBgw5\nQ/F2bls0ds0RSVU5LoowwL7Mqm6u7+Wlgo+fwVaeRceVZmozKFVL+77/xOU2\nKjERRJXE+Tgt1jJAvJAIqKP+71iP8kLRAZMNxyRXN33Ie2pRCitofLYMYfqZ\nc7PunSo0gMZZlsrtwFDruCfsI9A3YI/8ob3xFBwdLsHKCj9SOhyh1p4gPPvc\nzJyjnD0ytQGwD3SDQH3r6p8BAUE/SJP/hVo2/DCEhMB17zYKY+Hjqi0iNHek\n3wWB\r\n=b0r9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIECDU9O9wMYR4WsTj7ZHUFvG7GRxrvdrY2+M0MP/lt/yAiBcDGQLQ9sg2hMaDrX1gjR5n9smDN+uT6A0lZCy94Blgg=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4564472_1609855073645_0.3632653818083049"},"_hasShrinkwrap":false},"4.0.4580325":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4580325","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4580325","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-tITukR7Iro7AmJ3gifWYvsxF7KkY41S5SKpTSBhIxUk3Cih5h8KwTuZ2wKrYdCBL0pR7rWJP26pcpFctxeFUIw==","shasum":"757bd31de3b40b03ff79b538ef3c7d2a0f7a3d2f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4580325.tgz","fileCount":199,"unpackedSize":2736267,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf9yrhCRA9TVsSAnZWagAAsl8P/AmsP8ObVBJKiKLz+K/f\n2YjDNXImekIsGS/bLbxbVBb4/XpnqkDL4UxF3lkKlpnmbSKGGgcMqnFng5WZ\nDmxzCuRXbSrCj9JDgN0bKgXlIVMqzsSYFe6aa6Qs4nDY4nelfntms+THM8ie\npFpov2IX8hPtnU15XshQyhlXscWafnEsk1FATkhprdAurJO/cDyLB5yqnG73\nYRuFhNhqxkIMcduCacGDMGTGDvT6ivpN0gMWHctC9IogGVY7nJqOPRWlfE0X\noa4/7ivRdF2I5+3krpBFOJJo5mWOg4Zv3qnuELm9JbjV7lMe5CyNwhtgEwej\nHLA2rz8ssCRZdIKuoeZj3ANolKmglH1DCc++NSKNP97MBqlqfhKkSPlPUA6r\nHUjPye2h8yz76k3MVg0hg5fTvnX0pqVUKJLWtVTIfNGPeaxY44BQNsOnYm+6\ntWg9xqMaBu6LYSWe5MQg3YcafwL1i/S2CFLE7rcJZ6BaLrTLVKAf32YufaEg\n/9kb5MNZ8WhUwrBLY7Vyzq3WIyI65nf2GwFLIOMXI10fffs+BymGh1pF9BlW\n5T1jGjkabJyuchf52QaaTsjX1lR0/iVIWa0Hfvx007CY3fB2CHjl6i8+wcNP\nzidaZOAieCgy+j3S0e9/7xdZwLPV6/JBKa4SdA7fkGQpj9i6q8/oTcGWJhcs\nx4dj\r\n=OOjQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCqYmtldZu+Gv2iK/UDumZVEYwxbhGC7G7QJfk1teN1TwIgEsUEAf5FzDF0GC6/vtC8nWR/IEZCXdVqOvmLDfA8dZs="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4580325_1610033888917_0.011917994257395259"},"_hasShrinkwrap":false},"4.0.4602916":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4602916","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.19.2","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4602916","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-0ZIK1AUuyV0l/hIjJusPzVtuIzf9lCCQqmlF9sTGVyOUJNRbta8VcfWqDAopefTbj754nzF22p7gGKSdwmneuw==","shasum":"e69bb3391fb237af21e05569cc560a5c2134ed72","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4602916.tgz","fileCount":199,"unpackedSize":2738352,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf/sYFCRA9TVsSAnZWagAA+DsP/jcj4BvOp/ntDDQbtpVM\nsNfFtZ5USkSAVhNn3a6L0kHVaTa3+3aXD2Ov87Fl+Cq3perbLf4HbSyF8pnQ\nVd1RQt/Yn3XqShVfICLSg1Up0fOmBwoNzGD0/8y6ZhUhiZ255L8dxBzlJcUI\nw+/eZQaScpJOEtPUB7qWHNWF42AF1WXN0QeJKoolDMGv7DEj7PJKOf6iTirP\nB06Y3Ag6Kx4bYc/HyIu6Vd/k0XGdM/FxNa3fOM2SK4lEqUQA/OQ7fAdISu5I\nA3pVSjUSAjV9aVW1Nl5eqlPl02c43caoV/PveqAH7uK1zJLJioU36UQYeBd6\n8WJ4FP2UZ+TlphA2Tsw/shQqQSDQqdORH9lMzdSSh+R71Lo2q7WInxau9jd7\nKm2AmREmViR62kMGJnkKB2c1E5w0rYmIAMRmDLu0s1zd/DbUjtB9t1JugLIK\nRJFyhvEwN2rdCkxIEjrMmFVoXRdSAv7ERvfAnPLwtJIA0veqRMlyu2gz/orC\nZP1RLEbvSYBI8PnuCh5KqpeyRw1ge5HLUXcRtqzNcPeOZKoiVOakt7/dTo7L\nAjtEH/MBI2D2V6l9OjBCYWxLooqq0aQ9lv25+LDoM7X/KDC+tLDxMuzR0SjZ\n50tZJk/dIPELDIRaKETAFAJckY14FuexgEaqCTo32HqyZmwPBLpdRfwrk68Q\ngrFc\r\n=LbHi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCsAHXgFAReQvKI9aKTgfPxg1A6oFvNYr12knJVsq+HFQIgD6pcwL6cqyl+96WkDdDvizIA8vsDhtPJO3b+fA3cl2I="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4602916_1610532356804_0.4681722868646234"},"_hasShrinkwrap":false},"4.0.4603198":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4603198","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4603198","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-aR/wYIzsGRsBUEAqJoIhGmeZV8g+a+eLdPWhkDsYpdFYdMTH+II5jRdqA0uhinKRZAuLmZjqjBcatHfGGj750w==","shasum":"97efd1702ed88b6518a44e36cd67bee2d67ec046","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4603198.tgz","fileCount":199,"unpackedSize":2739327,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf/s23CRA9TVsSAnZWagAATGYQAIhgc7SUeso32MY6HsRK\n25usZBapu0rQ5fzzIF4k2sNWw80GrfC5oLIqBfcQ4dZvu2IIe5iglrNmfyxw\nWKWGiylVXmd85HnnlJZWsPol/vk3PEvLl5zyOIu9p+KxPsenTvEEQd0lilkU\nRya/JryR+TqqjltP0X402uK9GbtzXoFyl0WAiJM7x6fmca181Nnz7TvWd/4M\n/8FgiDDpyxM5Oe6sKr+2oAAtxl6XlGeuDTnnevV1HiP6BEQGzBcCsYeLdlXq\nuReDCmaGSUW+cIHizXo02slo2ZaAmazVIGu+u0XRd859NAz3lb31+D2+Gd2G\nLnHsOHWTVo7JyTSdHPabKonsyVKm6nR0wdCBgDqgnUrH3/CWXQRR5CiHK8zH\nSR9d2GCaF/b7ckZ9APSN1epdTv/LtFkG9fqW/gZy92S0pyojVBm0WSKJmsMP\n5NAhj2xzwRi16+galMvd5JRDGBV6gHk5MmXRm/LJ3MEHVMJpayrSunUkNzCC\n0fhyQv2eNdiVl0LPg5xELHmZXhwfQ8B8AAd2eY+NOz1RTuhiRqITpItREj5I\naqF414bkXmVV4A8/CUx23bT7wDSdTgPIy0WsO+coWEgFs3hNnvGlm7HV2z1J\n1IQasNv2YGtyXQ7+OPc5SAnDg76aRHvs7hwmeLs0iKsRj+CU4glCIoTzuIBU\nroYY\r\n=q3Ey\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDK58FylCW2NkC3Ime/gRGmBiFYsceEwelFr+XEPX1JfAiBhs5uOpkqSl2tCfnXXvsMJoi05okwNNxUqC/xp8mqtGQ=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4603198_1610534327308_0.5817071362822375"},"_hasShrinkwrap":false},"4.0.4604391":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4604391","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^1.2.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4604391","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-veKASUrl7yXOqY8U4RnH08veLrnwGGG+lXRQYaoWAQ0dprTp/nQGEEWk5eHJJWaNVJ10EiurtDNot//ye0uTgw==","shasum":"c678775d1b7eb7d0b3284c773b961eb1fc091bfc","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4604391.tgz","fileCount":199,"unpackedSize":2739327,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf/ubLCRA9TVsSAnZWagAArJIP/2Ua+edoVsCoKHP/PWrR\nTdmu5Jp9hxK0azI6v73pS8lM57mMLMeN90LXZXcBO9XHgrByJ3cwDcedxxM8\n5VNxkO+n6eoiz1eKIprLrjCLZbuG4klsZ3hvoQAMwle1HURoJEi25bv6KAj2\nZWyvZLxjsZErRH+kTs7jntcvr79ohpUAOFtAu6VA98wdJLkH4FWGfNCRts4d\nPEmlzhuWgIltua+nZEG7K+B3cag7PZN2w7OcBgWI0+imSGpW9D1W7QMxZdhE\nUplIbHdQVTqHgPaOae4xU854wWtwphiGUIw+cTyGOsNQ2ARNtFgbjBLj6Ebh\nykWGPFSi14HTRSUgLDgxtYgpx7ijy89Ar1EuhgPtpxx8lUkcWYvQgMKz5VW2\naEOvlSXLYaUhjF6xkcdYULb2s/nORBG5duXZ8dKxDVVDTUBUik8aq26deC72\nnS7xD3trePTJDQ/UFS4hA6f6ssZb4dLm5kuugqlHNWv5V711iVRufmoCDSFt\newtOoztQxTGQvzEyt8HG07FpNkuL+laVW2OkiCA9YnXsWpKF0rY29d2yI3QM\nD41fl5sQ41AmofgBkRV7MEYE5DtOK8OwkgRErDcmyJ/QDQOb6YDAw9AQ38YW\nxhdAoQvVKfi19yJqW21CVihP9dHoX4avYcPAq1FASPSOOkV+ONDTdk/C7tJ/\nCkIV\r\n=KSM1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDR4r82cwx25wrOYbpOXbtdy08FQj7o2vkYxyiUQjcZAAiAe9UcFjYEjq9hI1zENVw40dlV2UrZ7nSxQifPYTj5lqw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4604391_1610540747206_0.9000483758699496"},"_hasShrinkwrap":false},"4.0.4703121":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4703121","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4703121","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-mZ9x2s9uNJLQunDDdSjv0mLeq2QZ6XmmbQLCTPj0PN/wWQH4sE52mcU7DOsaTWCRRkNDHW63HFpxoGWPSvlugw==","shasum":"b33d0d61417b96fafdbae0b6775e6f17523e3223","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4703121.tgz","fileCount":199,"unpackedSize":2740041,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgFFgcCRA9TVsSAnZWagAA0PEP/j+PPEuFwLByIfct3NnT\n79kiKx0sxI9B97pMWjPHOOISeKtIUPdTDZv40BeKphsEk/Tvhaff2ikypVT4\nsMlPst0lYVX/jlMb0HwHokhoCB3Fx8hZ4RIpgZrxGFFS95/fgK037BqfAhB8\n9LQ4EyXquY+wgL84/PapXfiG570kipgSL5ZoRDTNJxa+cPaOqfvBgI/wKQOE\nWoBG4G8WGBHVlFkH3eQsH7gSgScZYePhQGfgIcu3/NEXjYCXPkbebJnhxhcp\nH+15zo0Re30SHaNe2ty3xLQCLOOkM0dRHgbTHXORShEbxZRxuQRYRM6YXDP+\nIi7Dm7g9RA63oQCFLr6lgRN6HJxRsAA0QqmOQ/BEUZsLxhUuyAyF0Dh8mgxV\nyC1O/qjn8Y/Ok75J1ItJoVjMY+4KmWi046sDTPKUhXgLVXJJm01k4oruKZ/Q\nu9nJY0CNHMc8N6Z0jn/6lRxECJY45pq91++FiMJI34blZzM4fSzYMKJtJrZZ\noQNstkP+fbjnOByXhSX/Untrsd/BIn5cXuqfW/zOk2Owgk0+4lS+9rWWkZ6Q\nmhLIFceQrcJWmsvWxbtiMOQFLwYZqod72eT1wUCALPC2xNjVZ+nwKyr02Pbo\neDYTFoeV1ORairJlKj1DWWRCoYcDTYpEg4WZP9u0r+q9N8m1CXCGMK1xczdO\nKLgJ\r\n=A4p5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCCIE1Mr/dxFtzzmnyOM5YG6M4525at9X+BCCbNVbALfQIhALARZ3n1wjoxYySujS5wHxLWZuIvxfKyeafAfkafFdLx"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4703121_1611946011751_0.3665490657805479"},"_hasShrinkwrap":false},"4.0.4798116":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4798116","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4798116","_nodeVersion":"12.20.2","_npmVersion":"6.14.11","dist":{"integrity":"sha512-Bo/xFF0b2YJ0/tYu62sty8x0AzluRfNKp47Eaf059eF1I8MNvg3uUDIDM+m3PTLXARcLDik5us9OWOKlw97+KA==","shasum":"45e4c3bd265989dfd7b35fa09bcac3c18e236a8f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4798116.tgz","fileCount":199,"unpackedSize":2740177,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgLTIXCRA9TVsSAnZWagAA4acP/0KRdWE0Vq11nr/2jbDa\ng8zvc6rmVzFBAVrC+A0xyx0tqqk4A6ghLCPl7OqmBIjoyrnWTitdcrWVScEH\n2GZlKF/hUtjLSv5BFZk6n0MGPrhi0rMo+j7AFdiopE/AoMiBUieFt2YNvEEZ\n+7caeMxsYoA/hVsOf++hdpZ1v43q+z8jkowrlxNek+3wh+K2QBejKYMIEQ+C\nGu5x76mnvDZXt1TFnFvQRbptqWbznH2QdT/cHct8+IXbZHf3PvBRrKjDviUe\nFGkwDtkVqtp1BcuME15YxXlEvPhfClVu7xHd0cytdgOc1YXhP6lId2Z/KMN0\nkAum+AjDN7ZcbBO4WKb1MjrMuS4Y3TJPvcVrs9ulgoQGcGSLOziZIyMp9d4C\nhsB+lxMtbZgBjRCODYchsLUuBICgqcFqEh2BmwyG0uZSIzV2pHw/vTfXWOLv\npj1Y5GyLHpf9+yAhlHsuPch1mF5LHPJ6v/dK/Gz2PRJvL0CRT7RITDFUsrjv\n+DAGKDRmzh8CDst7Rh+VXhXF2I4NOh+9G7A2YVdjbruAZLMZNYovbyvlTmhq\naG5HkN2RVsQSeNoCWL0ZWzxRlfVGMhvql/RVXoEAwtjczOAldkU89cauGLKH\nF0HmVgeJTgkFmj0TjGfkBdNEa1swsQrNITBKbR+xPDDi1TsRLtSK5to3wyEE\nkaXP\r\n=kvUu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHIJg7CHgPL8PpJmeRq0jwODHtGAosUMKLWbsndvYYOOAiAGpMDSerHE2EbrRMrlE3JONCOxB3O7Y0zGoj1a0Pby7A=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4798116_1613574678564_0.22077714518328828"},"_hasShrinkwrap":false},"4.0.4799240":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4799240","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4799240","_nodeVersion":"12.20.2","_npmVersion":"6.14.11","dist":{"integrity":"sha512-dgWJeL4HTvOk3xK3w11YBCYLlwJNEkof//KnaduqVw70ca4gyYsnSznPRvHw4VYk0nfwBmEXtWJEJMdxahwxpA==","shasum":"ccd9d28d158397b4975397727713ba737a6e73dd","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4799240.tgz","fileCount":199,"unpackedSize":2738760,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgLVojCRA9TVsSAnZWagAAudwP/iX/E7ExRwFPxOu2skby\nyj+d0Q6XEtaNDJBJYhlP6MGxBPZQ0iQVWX7EzEzzROnfL7Iae8iDmLibH3pF\nvtsNlKLOQksRoWUMGokELvEgPFZpXgktsEI9I1/UqjXpRDqc43xPbzBdN1EI\nNNsCbfkF9xlshNVQVzDE+Z8CVjDJy3Gx0+4gQ6WXh3RHgeLGf/xxy9bSE23+\nOawRamgy8n40AQrCGLFytIa9wqMgvaWHrgrGb/UmTNdIqOn2cA8qk2i/B9vy\nAsX7OPaikFoT9JzB71y9dMHa6q0Wl9MouI2X8Qpw27t7lu3ez92qroBzigMH\nRaAEPtF6HAPWL6KsbhgeW/VLJtwQwsWZ2p17HgVLd2MW3zfqcDvPpcLj9VjV\nXe9BaBrI1rC+G6GIDfVVad9NdjcgFCG7eaFn/swZbA6UmEdlNjh3bsvmk9IM\n2TuhKCUvDSHEtUNSG4MgO+WrD07OmIZ6RbvQZD1bsjiHdpixAOEMHShLxYp3\n1MJwy5+THL4arZIvpo6gzAIdvhVES9AnZhpY7v3OE68RB3ngiCdMy4p4EiWw\nlwEL8lqE5yBIwkLDrSfPsOAgcd/MNA0lmt4SFMz79DUFUDFWkFhpko0ty+06\nNGjMy5raO/EW5WGFKsusQfAINFb4VD2opVUYZuNJaHfOu6UQ0iZmJgCvZTea\nZ3Ts\r\n=fDML\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBMBlBd07EnZk8gXrVYtRUaCGWAUu57VI9/Fgh5iXOTcAiBanSY/Fs5K2Y1KAk7uuo5u7LkmETcDsjcew7sTm0O9+Q=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4799240_1613584930470_0.21756042950171084"},"_hasShrinkwrap":false},"4.0.4799307":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4799307","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4799307","_nodeVersion":"12.20.2","_npmVersion":"6.14.11","dist":{"integrity":"sha512-Gp2kouCzXPud2tyffTyHeptDqaZT2aNWpPSdiCI0vSGtoT+DSgfsbmY4VZrjmWV7vI8nzbWdzoNXK+0vgHRLHA==","shasum":"ee8917942accdbac5fa008f4bf1a0ba6f1513ead","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4799307.tgz","fileCount":199,"unpackedSize":2739482,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgLVyACRA9TVsSAnZWagAA8YMP/3TUW4YDnvTS+vr78E0E\nbgDUhE/r4B8TrCq7qX7t8dlRzrbjTb4DHt1RHyK0CiR7k6ddo0UBlkZbFiGM\nFh/+plGhsUFE3/6GMmOND7wLCZOvCxzGxym3HPBZ6Cq5dhyic3Y2rs/U6emD\n/0PzT1sR6+ygolNicxo4zqVZYd6LBMjMY6S3dSFdcRG0H2nlFDY8QJj7LASl\n6YRZqXJmfBZw2wmJAII2rsTbwYG0+OpuF6Aiau2pf5DvOilJlymn6TaJfMOh\ndAm9OBcxTdruYgzV6ptJC3jvtg7ZWhg4DjiZgsWuZNxiJNKmq38HS5Jm8jrE\n0GaZLJA0U8sN65oBs8Yvkn4CbyqqrqiLPWrwkeK4BW6N9O6ux+Ee1DtdgfMf\nMRCsT+hdttlMJJ+FJyJksDUwAZhGeG4V/O82vFGVUat66NvBJ2OuTPrrnlN1\nygNoCDhegksWursNKo3QcYzfd4E3Gex33jThTxSL0JHwaPlxp1axIM6iFUJb\nHyp6U2OIelXxi65gG0AXDau8aa82uVWOEy0YV4EbnGiM8xbTbXhBlc+Af0gp\ngGFjIsMUx9MxIjUQ4AGra7D2d0Wb5p/kMlcqtz2XwvMAmWFSFOIworrYR65i\n8U5TSEvrBvdrczxGgfpWY1Tbg7SwBFkBBZi19Tu/idfzD6LpQT8drpK0xwQp\nEgLm\r\n=tqQr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC5WDNtSXJtd9a9LLVd/AOQd4Gmp3zCTIQcVxFgB41lwwIhAOHJOs7lA6rYY0elY2QoYeAiyiMqUXQJKhfm0PiuiuZg"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4799307_1613585535680_0.6482533891137776"},"_hasShrinkwrap":false},"4.0.4799343":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4799343","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4799343","_nodeVersion":"12.20.2","_npmVersion":"6.14.11","dist":{"integrity":"sha512-5/Cg5+REjy9fD8lcc+hIqK5G4hVWkTx9EwxCCxAEzTlYKpyiXUaYQc90LlGTFG7b3lfuZthqFFerhgFP02bEQA==","shasum":"0cee1285788aab51fee4aefb343e7b11be46d5fe","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4799343.tgz","fileCount":199,"unpackedSize":2739482,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgLV2WCRA9TVsSAnZWagAAwlgP/RdPbDQtGXPLNEu5084y\nAYf1yzuKqwPlWw2gMxRa0R95AROrKmbAMqb99aqjlwLSXibehFzI0IwjXUyZ\n9PUyXs8UkVf5K40aGCaNwhfLDO7KguqkF0AxgsM8wkM0Zw/9SuF8qHdXQV5L\n2ABq1v9ajSpRbauHWE/mEoNWocBLZFMr2XqzHEJxEUvB5DY10+hHp5QO/SwE\nDIr8DWSv0YKW4RC58vhAtiKCTm8Pm4oeEOlo8uxzjsJHB2xTVK7K+flXtD+F\nCVWgEAsSPacS5QOGbh0dswnvlDwLbIZcJ1hBk5FO2FPhzac7uvg3jcOSFLK5\njlKGjCPwZVlXaIWuWl1oTpPrQH0FyyctIJWL+3gxOonk3JYs87vyAIFPZb6t\nxT/sapUAuYdTf+mHkcSOXrLiEROtwebqiwB6PMN0rpp3GxhCwtvnbk016mfS\njaZ4jGF/9tvS3hRY2AD7DqC4IziThk2Sp+iuSusSVa6zwcQk2G4X4QaXbAkB\ntTyR/4uZfnjDYSB8ozWdc3ausFYcHDfuLh7g+qevnBZ4zCAxCZguhLpV5Zjk\n7oTg1Ka7LTCWX0UT+tVEQJ/Dfrz6OVlRBdAGLKiQZcGGlrmbu7Nu4RLmHalQ\nF+Z5besLvpydxRJxOD8gCWNuXTvbEnfdKosQACs9qvwH3M1xfTXoHOuoIMKx\n6/KQ\r\n=ZreD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHG0NJC4EMkZ85SVzq0+vpI7sbHKfiNFb2KwE0NRdi6IAiAygEyeae/OScePzDKXt+0HVvG26njBbpD3griPddYg6Q=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4799343_1613585814084_0.7589266872781977"},"_hasShrinkwrap":false},"4.0.4824500":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4824500","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4824500","_nodeVersion":"12.20.2","_npmVersion":"6.14.11","dist":{"integrity":"sha512-qaUDM8vstMa/famkvEVcntoAU4bMRE29e7gXhIRImlDHuq/N5BNj9Fq7cTpkhJzaW4LiiINPn74BwkfOK2mnCA==","shasum":"b67654163f14e9df78401a92923fc251ee6fa67d","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4824500.tgz","fileCount":199,"unpackedSize":2739687,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNM7nCRA9TVsSAnZWagAAc8gP/0R88C61LxTZ7rPmH4jG\nqWTomC3dXj45Bqp+i0JpXryeBr7qD4tmqcbC/PD9CTVi2HBvag7tZSF1l9Qq\n+5CNeD1n1LmMnJsN88vFPPLyGbR29qxJuyejiZvMU8jbemMSrKKflLDaLGdk\nuphMI+x8xXhVTsP2pF9/SHTmk62GoZtJiQnRCvi/pY9UndQ8EXsDzSIqSavd\nSUzw8VCmNEAF58vKajyyvFw6p+WcbW504aMbfrkULleugPsGVQV9RzKsWxIV\nFviVc5DhYwUBpf9X0mOUsyQH+olNqzdPyR5qZOKYNN/fx38k4wcFrDY37HuW\n0omePmTHqivfsLaocVqTdwbV5CONUCDEnIxoNWDA5qu9JQnAEyBbGwlaGriG\nP2Iq712/Q8LHUAga/lkcmtU4cXvED+m7+ATEm/eV1VxrM/VDJed1SGHBMkRo\nsOvdkY7lelZBYgKZ+gw1YyUv2yrMqhYKLo+FaKTNErIZdl4vAqpo6wPfJqko\noXrj+5PjnmSgMytwbnZ4h+ww6TQtO6skSBYrofTzgvyx1zqTGoLjKhUSj6KS\nmCr5Y8ty+xvnrbFzdtdFTxO6P2rxkdUQ/KbLYlRVEMuAuGN1Qkb6tdYDur7L\nBMjZ13xZ52ktjPytCwWMwOi+SfRFmEvdhZGj+YMPMm+aB9HfEPTQhNiOi+6c\nIMAp\r\n=F1SE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCFO5uCNio9v7CaOxH4nHj91oEE29w7dCVmE1fkfx5JzQIhANhWyZ+mL+q9ZPzc43WGFY/rzMljqceJ3Soq6LvOkl7G"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4824500_1614073574356_0.521653787237764"},"_hasShrinkwrap":false},"4.0.4829096":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4829096","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^3.0.3","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4829096","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-fPFM3FfhMw6P/yiYW2GpKHxM5EVdEizdfOfjbfZJibx0OBGyep2DlhNQcGc2y17BHRjIjCB070QcPZ1eGphaRg==","shasum":"ccf694dcb0cf0a35c567362f030c311aaaeb3ffc","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4829096.tgz","fileCount":202,"unpackedSize":2746795,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNRzrCRA9TVsSAnZWagAAD5cP/0yzCzjKZ+K2j4oriIG6\nRvt/YfkgAjvtfhCXC/3j80UfJQ0wdXrmbO3Iw+PhzC7rc8zv61uKDVKelm/A\nl1cAhO1S0vTmwOPGZKvZjqJNevaU4dOs45CQDNecWdMUZgfNH1N/0BIyoMvd\nfUJNCcA1UPPTIcBQCUxKiDMkg5ngq8U0UBpKR+zdpNfKFa00GQYI0/i7GDRc\n1SYerhSmP6D/IgDZ9Pk04mDo/lfhOOeGybFDfGuFi9mtCXEydbNmEMlZ+TPb\nI4y6PJlf83VuNLvOFx+vp+s02g4mKXxlPujFZwn/U5NRPA2EvciIy5DUh6/D\nAtRmtYdiH2nW9m/PDOJdI7g/vT45G4gggLt40OgGY6RJesqgfvNeqfgsKkma\nSb56jT7UbpJI95ZhYvnERvG1eVw4jrkgghm/VjrQxAejTGQPd7ld/jPSpfug\nUx6RSErKmhCo7brQyBZ0pAARTIBFIBA6Fi6Nxh7fafK62jjhyNoCPNdJHjoS\nhGaBCM5rzl6HNIc6FPwQZMC3PkNzhKYjEn6uFsawUe3oP6XBRKTtf99auFL8\nv5+Licrh1ZT5JuuPvkyt/VmHb5D+G518U6+HObaT2goNEyhvUNXhueL70zr1\n0McGHPkeiMtz3rp8jDnKLlgR14ErZvovaccM4t9YV6aY2xa57nYIBJ93tP5+\nAX6R\r\n=6C0o\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC1mDcL7nSIalAiaUlh5YEvzcsXZ8KE/XRVGWQPF1tzrAiBuLCAuO4cViWEZ5YbAa+1k2pIuMLQPNg43/1pg26Gtiw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4829096_1614093547105_0.4866055680083414"},"_hasShrinkwrap":false},"4.0.4830031":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4830031","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4830031","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-KFziBDG4PT5fTWkqL7nIrQLIjbtjDgJRihpI/hXrvwKkD+FOdIODvw26Dymqa4YiUuQcQXx7ITEG5B0oa9Ujbg==","shasum":"da254ad650217bd58a718bfc2f95b77b2109dd42","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4830031.tgz","fileCount":202,"unpackedSize":2748125,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNTDWCRA9TVsSAnZWagAAc2EP/0Nr5GWBU6iJhqqgpXVA\nUJLzp3s3n4FTkXpEPaeSWsOpHGYdIHodZI6kRA6XsYWNrhKwhz9QbtQwerRE\n2AB90zk1bQ31S1sC1Xulnq5iZH5c4/f4nso7eoMKn976yNZZpds74qu8izNk\nJ7jrZGNjTbu270sN4HfO/Ryw05IVaCOPQpu2zJ8zzI/P7jOA/wBpW40wkS9A\nlG0ODTA+sV10zw5CQEhMksIvG2qE3h1Z8hmvi3RezrrY+l4S9bNmNmxMapmH\ncvAgeHdCmYfYF2iGyocEhxywwdvkH8GB7RX+y4Sb4nSwCMufnFKN3qWQR3+Y\n8Es3Ie2GOfsiSUkclD+T/XIe2h7FAGRrk65DTT+WCti0jrnfPV+vhy+1p5Ho\nFeHM09u8sqWNz0IXBxs1XCA+ptv2mQs5GxkkGKMXH+2dE7v5W5cCB/rh2P16\nx5R7hnXf6eazGirRnuiov3Q4uxupvYIh9xaVCGp+PTIDkwzQSuQM1CU8J47N\n6ClpcE7s/XHFLt6Y1+vA336Mhj8Sw2TeBvGPONe0enjmRkq4ABG4tn2yLil8\nU+w8JQ5Qi0XmfJvOWRhHIloa4ZIQjtW3cg5TGXS+JV/ytNWicN2mh5zLuTBa\nHaV9AqUiHHCH4YJRkGA1t32nc7TVSLUCTPXevmSSehA8rLGIZdZKJkVes6Bz\nNwCX\r\n=zkzO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEMCIC+QHbxA+1w+bcUvXsYzGG6V/ZpClDVTfzLcEQ9IVwR3Ah8ex5QB1sZbinYFQ/eynSsmuZdGJJlIXBKzgrJSHACw"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4830031_1614098645949_0.5532123748387974"},"_hasShrinkwrap":false},"4.0.4842297":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4842297","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4842297","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-G6wlLTg9yN95VBXrCB4NHSkkjzNlBamJjdiC+AUMixOqRjIeXf0yftWRc86qRia7rxbA8I/qWFMqJN0StUvWSQ==","shasum":"6a51e7dd9db5ed650fc61ef438f65fb7f58bd700","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4842297.tgz","fileCount":202,"unpackedSize":2747641,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgN4kRCRA9TVsSAnZWagAAbU4P/jIS/V6gIBdXmzesJ2G1\nVBode0OmIdEaOeIij64GW5wmP+tNGlpzr2LBf8zqUQJqnc1JwQdyXTyYR929\npGyqi8xFa20TQf540aol28JsMm9wJ5R8f9CO0P2Lg7z+cWgR2XMYZMs4CPd4\nAYBgQfSgKqbm8CLuq/3SdVlr9CFT2uLglpeVq7/0qmiM1/Lrv6qLE8S8Fin4\n6jOa+9hLqEUdzcuhyzYz2eM1YqU9tl0UDvsG5iaKmaO8/fh3jTqs1K03gZbR\n3dvSusO5YthIB4MMVDUzKjEMHEtZC1R4lo3dmvFKYCj2NGJQnzy9LeZ1M2wq\nMmosoQug+wpV/KXVroEqjprLOj97H5AlsQ8Y6DdJr7Gz+lwxagwTuU0pmQ6q\nYDGi6LquHxfTQ4VvWKegmqiY9REu5SZYWISdH0zGmpmRDLwiKdCN50njaifA\nj+wpoBpK2QqAqHxkOlRi6AMB0oUOarySpuWePYcNrK451nqFbZ39myPtxbYp\nhzngwyQKLhCrNuxQtdQc/ERy76CL8j1kY1CkwcALBAKEJbz3pqpyrDs/q2P6\nxUBGvNJTC7opI4w7bl3pOL/ZHQeb6MMalQ9aC7eLmf1uN8W6fKldG8EQKodr\nIxgCtgA5narIjgshYpvRlnNuTAKI78odN4GZU09zV6iGg5vt9qyhNXJh8Jkw\nAu9P\r\n=Av9g\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBRRA9g/jTxOA2ttHck13vIs9cQ2v29AlXKdw6rug0MqAiEArjdF66v9b7ugjGkV+CdIPB5C00r5bjdz+8SyIXH3x80="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4842297_1614252304456_0.13576486544972055"},"_hasShrinkwrap":false},"4.0.4848715":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4848715","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4848715","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-MIUri7OKpeSQKl3acqnG9ziVzrnF0NnSiW0BNpB0yQqVzYRRX1Swm4qcfkwx22PRryXQNcEt1SjkRzkORVdpAw==","shasum":"0db3a84edb47610003004094ce0efddb685e7809","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4848715.tgz","fileCount":205,"unpackedSize":2754290,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgONXmCRA9TVsSAnZWagAAaxIP/1lvAWoqRALiEnd12/Uf\n1/WIpBryb500Ybw6IolzEnsxYiJ+o5ic/VocHzIe1XfZX9lpkuU4RWzieJkn\nlaOOjjfq1pFuZG33gOxqx4j6Mgcm31nNhL7cnqdv1Kv0qfhYOP1luj6Qs2kg\nf9O8vlnUaR/5dr2fsLqKylgnD6+6s2ut7wZyxPMUoezjayjX9XdVKpnl+A8F\nYccvQZMQwPlXUaNYFqU941IRp891xEv/SFlZ3DYMw/s62a4teN4JS1UGRFwJ\nQ+qhoxnttxLWIRIOIp3hubfmqmh9hTP+PSNJTgS6nxP38yU2FUp5bU57Xc6h\nqqkl0Nwgfwba+6xcXWNqD3hRpIUKgPAB6Brk+AK1MGjQzfz4R2tUsMbtv25N\n93T13yeJpFiNqJtMSR23JlXffbZq+Lh1pAskz2yYM7ifsfkUJC0CH7YNRiSZ\naG/rYJCt8DsQnuBiwYn/Y+auFDzsr6PDCY6aZwwp+OFmXtm6ercjLcvB1OSM\nIt74zi+mZyjP2pSmaOQ8I7H1m8zPY9EASMidRXf1tcJvv6HQ5MWaQWglfkCE\n0s5/MxNLyX9eq+js1W33RcLVSpUUkzdNWsRIgs6+X+RvDBof6xD/SesKB9rS\nyx4dhFJ2C0DhR1VtaOgkVsji/moCHEAL913VP2b9fAZrNqxhUOOT3fFtrjC3\nnHBi\r\n=0otY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBItUcUHBS9ioB4MJfOZQnbjSpguDBIkUV8v70MFGx7UAiAzBOYQNrb1cQtSD7I82uoyY4bt/nmYXS/7GqDHf30XBg=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4848715_1614337509891_0.2825691965902064"},"_hasShrinkwrap":false},"4.0.4848863":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4848863","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4848863","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-CiBCn1b3UEkPWeHzjeYHFNVESghlNpoVXbHLo2J1gu4wWoehqaMFiQeLZt1NCf0LDifjMGXJO+A4nToSUBzLhA==","shasum":"ddef7b106dc5f4156454e9613541132df339581f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4848863.tgz","fileCount":205,"unpackedSize":2754319,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgONnFCRA9TVsSAnZWagAA3qkQAI1bKP+Fr5FIRe8f6y1z\nHGcPBPbK5CFTmgHoOFPi9jIxnP+oA7yQn3bH1Ip+oDv9z6sczUNiuw0j2EBw\n2ssm5LO2k6BmTgyoHB3LUyBrfaUpvDsnS15LsiZX0pnMefdkwnUXNybttnxO\ngrAkB81cqvVFMaDfUxxANIG01HRUk95JdizI1+q+nLKrmINCOWexo3T84AY5\n4DJl73eaApMgMTN+BhqjiBdguRe6ihozJ9y/Ox4EKRSvB/pqm8wuVHucZvkt\ni65DHxhU4colHnUx5Dla125K3RupUHsISLN4v8w3UyiD+dCKAXGeasdW4Iza\n3EXAMnXhQanzla3jzF4bAJS1jQpXrgWE1EpEtY8cfpSRfQH0WVDjgREVFaKO\n42xyDwLzSQrtnz5vozI74ryqBSWH8MFLGO7d8jb8wYtj5Gcj0ONFvcgrETH+\nsCdHwxnpaLaQIcCMBoM3q54Y599gPdysyZ1jSFS3GjPrt0yOhpmD5vEjTHFr\nWTcPzcNE3IwhOPgAKc31T+81zUrP9dn5xktSikpVv5xKhf682sd3S7S30V7p\nKEh4mzxTKGcv7gl4327S+Zt3vn0QLMTne9+m3PZrI7ep1JL4Qr0Sd3IvcvGv\nA4faUc5cBJlBRCkiMLT8LFUcWx1WPUyafkUY7wvLln4znYolhYrJsM0nJSUu\nx5EI\r\n=M+XL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD5QOgYZSPMhVJ38Rt4N0vSiPJr80DbEKY7cUHjQnUOHAIhAJCW0uxP2zA8ahHbB4IudR1b74pxYUJ9xxzx7C+OH7tp"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4848863_1614338501348_0.2878117866446761"},"_hasShrinkwrap":false},"4.0.4848923":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"4.0.4848923","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@4.0.4848923","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-lyojeObF9V2mTPu3B9VK41fPp1cqxDQbq7k3/vPZG8nBErZnH3es72HqoVhIPIt/j1voZjaYIuY7RMnRfkmATQ==","shasum":"40b340b0a90fe0e44eea9f3af7fb1d506088db42","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-4.0.4848923.tgz","fileCount":205,"unpackedSize":2754328,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgON7hCRA9TVsSAnZWagAAqQgP/1HlvsyADBHYB5+ntcA9\nvQo4fDEvt+uYHEBslKu6fYmXRQXh4XvMs1vly1OgMvOWJUH36WuQzDxzYXMc\ntH1gJJ/YXS5DeUhBxjk8/PXJi2ccIQ8aSJOHUgj2XlRWxuNJsiySkU3ZcQgJ\nofewyFLL2YSQrntNALgEpVJt5Prx2JHh5J7uocOiKRMmhHMOHCZGS51iQz2b\nSE+aVU9KiXbvSwhH62ovG05F6GCzouGt/GlCEAqqSUAsy/VVKiVLIEguv2CO\nqkGRQxLJu/oLz1ioGktxO5271UKh4YAxBp3YS+9SF6NuLaz1Q9DQpQROddQ+\nbMblTEd302bImy9/p7tfnZRkTmvCooyZT+LuE53jCk6CpKLbGxa8XTXGdjeG\nBRL4jDjDSG15dukfaZOiheGasznOAoJZSuns8Nb2djtjJz87rwSZVCay2n4l\nZyjSlHikBcIQr/2xZS4x6uYdhYvwbbdHLUQ2/N/cWY2yXJER35Fa0hk9CpC5\nVigVXRkN75Scj655Ypz5/ewk5j0qd7aNMsVu48z6fQQnPs6CrjtzgObJxF7/\n2KCZehm7a19sy9Zb2Fs4NDwdE7Mk6JZav9bHGgjTD5ErB2EZ7VVUIAhgL4mF\nIJNtxc6hJ5EP8jO3WM3amv2Bi4MKPdMU8EoeV+RSKv/aLgA3TO/O2OeJ8O/a\ndWQa\r\n=ihwK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFZ4/fpo0fypvzQjMwrGn4MT1bdKxjgFM9umpn15JYLVAiB+gYm8x3NlLdeLQKVUyMUR0zHjRSn6u46F7WekFP1pjg=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_4.0.4848923_1614339809257_0.9607193820626707"},"_hasShrinkwrap":false},"5.0.4859830":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.4859830","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0","tunnel":"^0.0.6"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.4859830","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-Gm5kVKUWUaOf7LlAKTbQn4EnTvTRQTjQgI9QZs8lR0iU2UeoMCnmkIiRoJ5S+oLCfVMVaVC7zdNdDsfEja7SxA==","shasum":"8354b8dfbe921b32aaf1c69259fecca7c53861e0","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.4859830.tgz","fileCount":205,"unpackedSize":2754328,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgPQ7GCRA9TVsSAnZWagAANVAQAJHm375gN4MjUaow2QDe\n7Pqo8vBbLbDPuNG43CFmYxf5cSbYSfmy9TPjbuHY1WgQwHiwUbgY0vGJE2OR\n9xI2H0mxpU1tFHO4TRDUSHRGPc6WSX/e4OZrdlQpBGp7CmDLN6VEaX+6P0iy\nbf4X3JC0/0fUxBqwKQYDoA20geLDx3kaxCaZOjd8a1d8BJ+LzvobuoEEgWnB\netZ+iJXIXOFduWuJiFU2u9V9SNs1VTTBcaqn4T9slzBTKMGHUStHDqFqPo0/\n8hoQRxbymwy1ak5YuN4+ffbz2Phs2sE1V+JcK+HC3kwT0qHUwvhe939fxW1J\njT/OYzzNLV9ySWPvKIAr+wEUOW8b0KWTeJH9VWtJPxd21dWmVOWndfBF4+1/\nQsEV3eJgutaKOrecDVKDmegmoyIibVmOhIU653Br1sPY5zdRorwtCEVoioV6\n3ZjbZbh86UKBo2BSy3SOdCwHxuJ9M8XuSv7auWkRbOKpgiKBDPW9g8w3sOrf\n2fWFHBgABt9zd5n0izvh/wBEygqbxm3gl3OUMQJBOuOx+3XHRR9HyJRZTVyf\nxAKoObfNBiwD+/0nwUDJl0ivle8gavtlWy0Qhc4JyeSyVe2c3EnGPhtK9yKz\n1RnPlAciVYv4GmsKBwp34sVviH2THjuYLIRk3fmUKgKSNF1AiZAqSrkrNC9/\nCUUn\r\n=1qAm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE+Ok2cJ1FxvYO+wXEG1AnY9lvPVYxfkFDZaOxpXnslZAiEA97Jn4VyMu2ohKokJioWIFYM5tZLFESiuIDSqe67GtSc="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.4859830_1614614214250_0.12690212074283447"},"_hasShrinkwrap":false},"5.0.4876842":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.4876842","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.4876842","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-0ptVdrMiWfV3qtK35eDlXusJi+B1stK1x41clZhjfA5vVZLKjmuDXEbVBxFzRGefLCwL41Rbx5E/9JGP4I0fpA==","shasum":"28bea3efbdfe9089edb238dea16284f0a2242742","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.4876842.tgz","fileCount":205,"unpackedSize":2743780,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgP62rCRA9TVsSAnZWagAA9bkQAICgbn5jtU5USlLDCzsy\nX+hCr1Q5YnGlCrijQqG/WTv3eYi4iw6+2FnD4mjpv2H8U1MbRDG9QCoSiINA\nYAMlrxSWbSd/JCgT9fIn99EyhDNMaXy27i8GX4iO2uG8af78jMrIgxFeADOy\nOsS3nrDlE1EsbWNrEpy7AIYBU0IdZDHYHHKnYQUy0ur69D4aU8wUSaimGv6G\nbl7MlCGSZ0ya3po0TjMIcqdlonCneugK4tCS2DVHeyTLbqwy5kG787ZqEMc8\nXLcNFXaXFpJRwGK4rP7kDHq3gbTJQJQ1Zt+r59c7Xs2rucLluYaj8IZUnbxR\naHm4ecbRC+2XH8gaiMfbeXoFe8mXdzwXs6RDxsRvY9PP+baQPLLn9yf7wkgj\nlbFkm+RQMgYdfvwsUDV+GDKMg7vyGG7B6dJVwzlmCm8prn9gm2p7tF31jw8h\nrWKBUmVV0Z5YGzQmiDFB4dxUk31w4GhFhFhKnmFbeH+5ZSff5/IOgV92VdMG\n3knKh+tRXisjwTR29Sp776idfkS/CYT7GBZg7BgKNub1OjI839H6hyq7nsGT\n5XbT4FpxhTTTVS65fMTghOa9/4kYwk4wSE2heOv1yOIMr+lD6uICqGQI9EdQ\nQBoW/F81QBNiUg+kh9rM7wNXimk/OLdQjqfV2szI4cClBo1kLhoVpiZzkSpl\nq2Uk\r\n=YOXy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICMYoPxhqW40eI96yI6WTOQyCeBxGfMZ63nlfL3K5wisAiBld2xMnjdxBO8rTQqiI2csQu/uMKvKWkaWYJVagHvnPw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.4876842_1614785962730_0.9363156994128454"},"_hasShrinkwrap":false},"5.0.4927889":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.4927889","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.4927889","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-pcwQGxSym9BwxxZvfZK3slZXJ2KW1udDP+4+I6KyA2DZp7rcuhTZb9gnCdWZT67hFBXsM5w7DeP4naG5gjHS2w==","shasum":"16fc4d068cc3bab25f110ce59037cf8167d02992","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.4927889.tgz","fileCount":205,"unpackedSize":2744272,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgSkFmCRA9TVsSAnZWagAAclYP/RIsSfLl8uuia9AL4AOe\ntyVDgJxk/tcfOhE2h3FzlFjwehfWWNBG0Y2QP2ko1itQXctCpsysAssa6fQU\nj4yMZHoIMAn+bUq9fDCmF/56MvBINYKWqI1jPhPBPqCp2oelXvzxA0k3Kfks\nvYCgFVMZGNDh5vqhCFjo8mEaiOMA++obsn5uk6qKTEDmYd+aBCxrcn5d9rbP\n5WzA4Qmgb6LhewVQcBixOQRq86gBUuTymcZJIBqauVn0SD6ooBo2M5Da87/7\n56HWZRXwMrVhJoda4CxCQZNCu47rXOVJzSQXDk4Io1uGvl0Hk+7Y74kKx+x3\n9J4wdB/rIlJ52G3iqJev3g1rTqItrFIii1vZMVpvMvW/AirCE2/8hK4j1rf1\n3mRQuTGhSXYD4GsIKqoe838lsMXH7PhbnSDzw9ZooIcfVprtlbuR5LqVRSls\neHY+lEBiXgbyeU88BaXl80OW3t6JHAA1uoj2vDI7sCkx32sw2H36xYBYTlPf\nLGE/e+8+QAE/LxIOyLad4PSk73ck5jQ/bCt2UKTZUVc9YYos6Ws8NE8I+NWn\nYEesBCt8HAoRUcJ4nJZ/Zh14NhZKrRKuq7Co/2vP1mdTj8Klb8ftfC/u6WEj\nxz4FqBkVxiSwraDfJapOuOq0B1no7Y6yLQ5dy+nCaUr7A1LZbEJ5FECHaY98\nEXtc\r\n=fQf6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPxjvnb/AK0pOiHTXpGh9MeQnWB3JHH3FVWNDqq32YsQIgBr2xpPttonLz8dhmo+HWsUatJn20/wz5EG3OmmrgBL8="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.4927889_1615479141977_0.4630984459502956"},"_hasShrinkwrap":false},"5.0.4961252":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.4961252","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.4961252","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-9VjUD9sT0ZguehQCucRCQPSRJt/uYXnCJAyoBrixc2VEiB4hRo5MH2BZzAWunCBRShLGq8cnm8pZP1AtP7G07g==","shasum":"274428169885d2e9ba54d5a1dd4c44de3047c906","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.4961252.tgz","fileCount":205,"unpackedSize":2744334,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgUkQ3CRA9TVsSAnZWagAAoxQP/0noqpUkBBWQVnnWfVaQ\nEnG5VAbgTLqukx9GOVpJLjj5lcFhPEfdAdwj9RxbLDAhUApB9LtA4n4eaqEQ\njKNIm72paEvuhjGyje82skmUdo5rH/QdIYZhBoK8Pd6uVqH76jhygIVgx0H6\n3d/HTUONAcY5rniVZ5Co3Wo0NTq0YAcdWGXnnqcXauj6SyWN/QpzglfqyT5D\nEsAft14bbdvZfOiqR9u2GF2nwBVdgFF3ToArkD6ZyGYVqR4vnHc3pIbJCjCR\nt9h1isAydkEaaZu0ICWm8VMuXVmz+pOlEqGIZNo831fuVsD8pv605HmorOkG\nf5ofNkc6mbXQyS7PvCrsveE6Z9JvV50vQN3b+/Kzl8QSZhxyGTthwVPJTXr/\nTrzaoU3yKJvYh2b8N/dovz/OOTPpR8jxqDwNg/1TN2QR+BGpLv0b39nL0UCF\nTuqqLAkVioXoc1MQevn6julWGWpG90TB5PU6NojzGGUJZWT/YNIOpGRxMkhH\nN8cw4a3wUeEpw3uPZ7R0IpKFE/Iag/J2Zfq3RDF9ANiQ567jtq9Uz7b4inR5\nIUHvaHdB/94fkknYGRPNmeOC3zEMPUOkJ/YiWFqKXucVV5+i8GDEgWJFf/fh\nOA2WI/pM8Kck/TI+TYNDs5xXfNYkF7iF7oCH4JSD/fmjdLSRA9koWpHQbT+Z\ntZwR\r\n=1cRI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBS/zaeB1V2OKJGM8LkzOntSM4wHN+Maz/B6uzEQzTgdAiAorr7oHbbfPHNwe5TR8jUZ5DlAjI1wnaoKD+VU3Hj95w=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.4961252_1616004150992_0.5575192246892677"},"_hasShrinkwrap":false},"5.0.4969466":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.4969466","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.4969466","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-cg9+zhqF9obPO0h3vYOzbNWknzTcc0l7XMpuxIfbrmDxL6JqzO2mWeFg38FWfEzmmmOvaDTgnB9rjRO/b/EG1Q==","shasum":"4c31a21dfbd79d09b5ac3071a73253d40e2e20ec","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.4969466.tgz","fileCount":205,"unpackedSize":2746965,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgU5s4CRA9TVsSAnZWagAAgQEQAI8VpILOeZQocKYGF6Gr\ndOFAb14w7vm6+fP4rtzWSpgpXU6duHmhupZN562ElzYXU7nQcnFXzOXo3Abj\n98kTlYoQU75EMnqtWuNyTj9PU+u8QSxLiS4S4B1srbvpdHWdtH/Ha4V6ABP3\nRXgbLwj1kzSwK3x7QIoG6/Z286w7fCKuOw++lUdqKYQX5NdFqWMIgTVoKRXg\nmaI0ewJmej1eQe1o93uDSIaLpcMUzQv/C3wNbkNuA+E6inR+nvgjS1/jegLo\n2MJ53YH6xnlUr84SPfDv5P13Lc91bLzHxfVC1Vk2EkPm3t9xKNm4k5BnK9cb\nytVzQXfkBY3QAbHK9AkR9gOojm8b4VoGQ4MubGFLfvpFoyEQ78xPE1WPhD/d\nNZnevDX5fq+D2DtryF4eVNl/azRIpCtolenAcK7VfEJSOEkT6HZ5yFHdSN8V\nlEKVXq6zNW0KdG4OTYDFFtQWTVkAMi2htS5nUQydC0KLGRVCe/fnjD6r+TVh\n5/pzkSfxOhjsLT61b8vO40IIgR+gGJRYUKjPLZTRG8M4njbLVzRX5SVVl74k\nuEokJI2vtEkWqtdc8ZJG8JF2IjDlGwVoFFZg4LrCHcAwFkBIDF2fJtQSLzWM\niZ17fRBUiGG1X7OCcEbDwSjDv93Lfmnhth5j2nmilqT3eGz74imYZkwNTOah\nEk9S\r\n=T/bF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFna927Lw3sRBx78hfXSbrLQLwjylopjqxENH6RBvX7WAiBeydqpRWU9JutSa/iiQlyFpMpCvecZ64bly4lN/V4MyQ=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.4969466_1616091959478_0.5561575127773413"},"_hasShrinkwrap":false},"5.0.4988301":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.4988301","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.4988301","_nodeVersion":"12.21.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-2DBJVQl5n8e6e6P4j0E0IneaPpw+PEdKorxKLHjZbBvV3ugbVSwG7CuLipdQv7DtLpDGx5xR83X277tmxXzCPQ==","shasum":"38e0737f5c1db45f3d42e257db21cabb17635d44","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.4988301.tgz","fileCount":205,"unpackedSize":2748081,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgWNqGCRA9TVsSAnZWagAA1C4QAIFR/RhZkbXajS0dTIFd\nIU1QrSiihi6yXojVqBFRP0rl/1sYEJDZGR7c7clHPOm80rYMphx4QW3hR03z\nT+ZPKLiPV0cNmYMPeiNqYA7mfgYJYBKTWbtshJbsCA9PFonKy5gsU2JM/16r\n3qrZ2B6brLxTQ1tQ7SPzbc3Igfv/t7Jn+jA1OH7gUo4Nh6JNgjQSdn8B3E+g\nsQaZdPqLMYd15r920M2zuU516pagWap+o09JQBzrrSQdpoqfU19garYhJpIt\naKn5R9JSHfCXcW1wyxhuGx6KjLbBip+8hwrEc6ZZ+uJuI7cQcC0Lr9GF04Pt\nYmCgadhgieEkubp5BuiRisJqDDQvQCC20DWhy3NmpqFT4M3zOI1UOMqMdktc\n6CS+zYgDdUDPIpV0oaAlXSaw4Vpq5H/pdqt6zjZmLNZpL1qrV5GfRoXbvnsP\n9W4pnfWoKrbPZyZSZidLcMHUBtFVNcSbniw2IGccgf1Bix1btgJt4HiBHZIH\netlcZwjg/dCwWSyGvIJDAuYd3slIzxHz57/i15XRfzxwLQSp9kFbVotHEXb1\nWrz4S8cesuKHY3afHNtmPr6nGHUSVIwh+cAOL+G38p19gpzdP+JBhPsGDOqq\nCdu3wjjxYM+r3LhApSi1xa73oqIkjyHIcyA+Ckbsfpptv4mEbiQ3Zvxfs0O2\nvczz\r\n=VdVD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCIHFfAh5sv/9kJI4tUt1bpyLuGHYgmDue3raOyQaE0/wIgduWsStjwY8fhpgW/bEKya26RhqkqXwP1fTm0W7L+LVY="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.4988301_1616435845869_0.3024166118213423"},"_hasShrinkwrap":false},"5.0.5098713":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5098713","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^4.1.0","fs-extra":"^8.1.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^3.1.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5098713","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-Zgxi2RBe2MAulsQV0eP/lcyHDhNze+yIMr81EgP+im6s+N2GOMhzXrSktR3jGala7+SLfYrl2GSasfEOxuzDeA==","shasum":"37acee52a6880320a44ac791be17b86d26447892","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5098713.tgz","fileCount":205,"unpackedSize":2748081,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgdcWCCRA9TVsSAnZWagAALNEQAKOM8Szkg1Ldf6kRaHti\nzKQsNHdhmlLC3IRs3XidlpBVTt2yGqu/BRai24b06e5KMpzmKB69a05ewrzN\nlxVDJ/0hwhv4BBvEQBz4joj1ITe1748I7IwuYmfFE6IELTWg3wERKXfMBGpx\nOFYFzNSLOA3Ej/mrKI6uYsPb7TSKgp0AJT8p4QlDkdjxysl30y8jdK0JcRdr\nge09iDYd5A85NkHurmC0lTccbmdIn0M7cg1kasj5Z+Gmlbal4RshOlOvxPPC\npU7sIgb6MeOzcTFo5HCXqpXkzGnPFzghAZrus5n32SbJ34zkYJkxCrHGkwIH\nsoZ6L2gnJqiJfA1FyWyVdepbBzs/42xY+6RAfzVgTboIhALwGAL8vaA3+S8l\nCVPHWmaLD18id7kPihS4mmGzS+WOUQnZMYDhR/hl0FhQ5O0mmcgORadvHPvp\nhPEOgMA5kVwc+nDbvt4Hpemj+5DWAt6aBs5WyZyTX7fgvldBs5hmnFsdpd2x\n+Ev8TPuorQtaxd+J8Gbg49BbIg2bUP90jsPLuBqj+dvRSpZk5J8C+ysgc6+j\nSow8Ex6LaNIvk5MoQbzY9dsIIAko309vzXIL3HKBhX94pJmur63SfalWH6u7\nP1LOTlxDzGQsTAxBsG89S79floIiUC0PXBN/EtGzLNPw4u4oE3mDYhmG4Dvk\nCqLI\r\n=Egml\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB1Bj3q/f4eDLDSzjAo0EpAxePyWfuys+/V5C9W2kWq+AiA/O3lfskgoOcXzqTw8Fh1VWvG/BGiFBojJPnkzm0kO3A=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5098713_1618331009749_0.024984150021766016"},"_hasShrinkwrap":false},"5.0.5156024":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5156024","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","lodash":"^4.17.19","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5156024","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-HXbEqID3DcwN9vKbZYgnKOa49bjsHDTr4EFv6im4BePMmSzlvOybImy0HLeYC4J0D3VzNkksq/Yac16fsHD4gQ==","shasum":"fa94da85d80f2b9f3f15708504f47acdffc6f8b5","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5156024.tgz","fileCount":211,"unpackedSize":2742955,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJggZLbCRA9TVsSAnZWagAAYhwP/3WGt7K/qt21cXKCEH7e\n18AQa2K4u8Xki89GMPQsAY0AnyqaLaO2k8DKhMDiorsnfQ8qZNfYuIRLvc0t\n3mKxxqh8I4NxMfxaiMoW1xqrVyXY2LT/5GCPNJSrE1mZN6WPjSI9DfbJ2raI\nb2vzdyqVphxAFX2e6ohNAdvTfhPbUnV3F7pj+WGP1W1tZrHzuy+uXzSzXjqZ\nQfP4iq79Ouw9Ft4kFq4H4kWTmAg7JElZ1uk8UsJAg1gF/AhHo3Hp00y5i+b6\nzc3Bkwsj9h72JcaYb1UFT3fmTokIKSAHEP3J7FvtoDxNNGoINEpWKJqEU3cM\nqpJO7KvphM2P3nUAmRgWL//JCFbuwRUT/5bYXLNBBxIr995g1QUs08FBY6By\n16XcgjxSfPZIlG5g8xeeKWWVP9pqAWRyA95O0EKQRpp7EJVmYPZTnrB3RQav\nZHMp4nxmHecpWjprwRPVGP8k3eUe5CTp8TuNqhzAvl1pC5oL3iisEOSDE6C8\nfaQr6oQ9NjqqtBSCUoOlRk3SLDMrXjgYsNHO2xUtt2X0Wh9vwSKP7bp12jSs\nTcYPGgzU9aMIlfpgrmpSc18TwtpfZ49FBHzSFZ1bWnVqV8e3iNs9uHuWXfKH\nk7KVPWj+jSC97RC2CeYBg+V2K6/ojIAr7nXbeXq6/3B5M3ORsvEqmrBY+6nS\nzylH\r\n=1Wzn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC8DAsCQGuCK+1/7SuVW8+44RH2+/ghRGVn21/Qjls7QgIhALaKDJLei17Jhbu67ocnrYq8qFL3UZFm49I6SudSTyml"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5156024_1619104474198_0.032272891788516"},"_hasShrinkwrap":false},"5.0.5185212":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5185212","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.0.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5185212","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-lCgyWhdZPmsWmEmLXPUseavt8liyWo8AxmsN2JlIiHH/dFO2eEZbC2nhLLUK7ZDJf2soJIBbjpovZQytdXLh1A==","shasum":"471864c0130f2553a5a2f78f2f20775f3b2b386e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5185212.tgz","fileCount":211,"unpackedSize":2742788,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgiVAxCRA9TVsSAnZWagAAQnYP/R3KwNQpVzja/0V+j174\nMwEhmHVHT4QzPZHKevomi6yS+qSqoFKJ2fQfzMbogvl0lUZAegU1LX8EqAY8\nTdKcmfcUCjV5pxR54v5SKekL0ONr4g9E9b9edQs2I9LT+BV4mYB1AyMl32bg\nr/NETIhSiWOY/48ovjJwgPJi5mlkPe3VzXXVRwIIYsbu8JVqpcoH7XUFMf7M\nbspPqmDWyFZbb7KKE3MOXNB/ll3Gh86lozHMHBirttB2+fDwUjOvccNZ5Xod\nkbTJVwvYyhuMR8YpU9ImFzJ4z6bvNNeCtgXt4UEJeb9Agp7ewkLcT/GenThr\n3SjHQCHRXu2ovBqYhhe5xkLyvEP0SjGpgKw24gfa9v066QOsCvWo7siq4dMi\nzrQYI/W17ANdLs+38YSHbt4EbrRK7+MqW45yHetk5oNCr3XZOIifVhKMze/D\neXb603h79HNqZ+tAQx7ikQ0sTkblHFpT60JIsc2ova7TgxnQVQO6BWxwrtOt\nD0jvla8dpJQ+caAqHUn2VwCLHWJc205mS7tirg9zkqYFyrpYGOPs/OTrrQyN\nmWilbrrORodXHLmypZ1ZleCcOn5+hrWlD90OZNOmeKXCgGICVs/YgYr7Lwdi\nlg5tcwYvZ8XZNUZiwMv0LcgV2mjBwjOJThTxYCooKQm1nTwFWCjDTJ6aWjVI\nZKtp\r\n=fPO6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBiY4MhN9zCJw/urhtNt860GIB+zoAizXieZ1RZzVO7GAiEA75ox4vWgMwZOYSWnZpdNnpEUkZNMBdQAIEM7la0uO+k="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5185212_1619611696973_0.5791255665764996"},"_hasShrinkwrap":false},"5.0.5200121":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5200121","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5200121","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-D1OVoDhY7WpEd2powSj1W7wym4kTHB5X0fwKIgDYg+AUtvpxnehNShlc4mkWaX1hJ0U/at9+tMqdVNFG36kIIg==","shasum":"19f55df71216bb32e422a534fcb5d7e8f65f6312","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5200121.tgz","fileCount":217,"unpackedSize":2715821,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgjDNoCRA9TVsSAnZWagAA9msP/3HIByYl9F7gIJJcnR1T\nsm450P1fxvUIgvGfDvAwCcV3PWe4pgE9UNS9mz4dBjah8wfmyiilPdgm5n3a\niHOdK7YftChyjGPW6vV3ObTg2zr2n9DOakQyhUYe1V/q+AP+yPVj3w90tdoQ\n4dYLf6CGTh2WBH05icO21MHENCssDX8oULtmbmHtXt3ckWxo68iiY5H+Bp8g\nMmkVfk2QKQtqHN9hMtd77Iwb9ZFNXp576u87xpFR1EbhmnERwRY+wXJNa2Rl\nLg7fb/WXY4ntoBBqoZJfjwjoP3cfa3f+VYZgih+xR9GbPfweReJFt70OBxsP\nv6etRVvCXxdSjexTz1437Khk11wduBK+aave0QEaQwXH/NHOKVdZ9rTyF2zj\noe+joGcfqWo6BvPt9QlPyzcXa19bY167dYi3BQCLp23s8qlYCy7tlHYceq5M\nTm2Z6C/xntPEBv8gOB0+8F9pabSWAOWW3HNGHCejKFoMPnr45PtKsaGtPKOR\n+GkPHVD+dZa6kLpZx1w1yifEWLFX0IZH8J+7kaV7abFMegm0q9PXriOu0cm6\nqm9F3aLZOgKgZg5FJ6dTrKlzblnfGbxUtv3095Oa1ZxTCWEBCmghyDdoOd1K\nzd/Lt8VDn0+5FiaG6UZPZ/hmNRv014tZdGLCnAMC8PFC9j9AglEybyCQLlN8\nNjHh\r\n=OiDe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIECOmoFvpyud6uLqH7/bFPi25N+4o6ozWWPfb5mtGtqkAiEA/P4LU5yPI2Q5BOtje4btt3soq7g//R45xjg1fY/pU2w="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5200121_1619800935739_0.6221931563626277"},"_hasShrinkwrap":false},"5.0.5353744":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5353744","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5353744","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-p4D0pUTUqTaHZ2rwKNKUK1VNl1QnI8XlrJsREUJi7xgbNaQZ2NWUkrAWKXzHazS3GSZwyVpfH60pnJWTPZpAag==","shasum":"24dcb96edda1e8418b55a9af8916ce997473581b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5353744.tgz","fileCount":214,"unpackedSize":2709187,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgr5+JCRA9TVsSAnZWagAAdwEP/2ejEi1mAVaw4aH3KrCm\nW83gjF+iSPFpKplJjzak8tdIyaeFhbQNP03eaftnyf0dbmKIEtg2agmdz2fG\n0iftqBdtmzsG6sgPiM6qqsTZ9vb2dfFOG5QIJ+cWgiib6NaVM03Ii//PqfnG\ntxk0BlfesEUy1CG4BENLxMsWGaff2FOFo0rgjTRJ4ktx1jTjx4llil7gfDaY\njCGmJd163yzoqd+iGvrA/rEKd2CU6Q+w8jIQCDFVuGcj+mPNWb+a8KCfHAUx\nu9cyBw+/+to9ZTtHfxeFVFbROLuVi6lWRZDHPlY0vSqxoi5jezzj+g12foZc\nYPJztXRlkod6fZ5EzlYTiyOkGt8hH0rgI/HEah0Vdbbh6hrisp25Lq1chKuv\ngMwQHZai887KlZ9/dp3P+BEHk6uzJ9FxDu7+Em8CHoAZMTN8lVhLQbjgkrEE\np+B9ozdQJnVP/CY6TNxdPFREegOta8zSY1En8G2wySeK2xVsee3eVfNAMdNb\n3JXAKCLXG2fAUayCQ16YXqflrQNQiirlRYvdbrLXOxr7T+62aTSmFyw5//5S\nTLSF2b35qBbu5blFmgEmSv1c0LVG/ZyE79IEdmoYeIoQnZbEdACnpjPK0Czv\navEYnxWYULOJ9KACy30lHOl1bN6Gq5FjZYNyjVYBr/LbF5VLtbqNi7nfYDWS\nLHTl\r\n=NlyV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBR76QMr59mDC0gcxiV3pgxc6KiOcY+AS4Pdx7ZEi20PAiBBwzbdjDfsR871722b1Wge9+9YG7dOGkgb2KLonWJKeQ=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5353744_1622122376611_0.8692239793398611"},"_hasShrinkwrap":false},"5.0.5357219":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5357219","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5357219","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-HjARTP72BYPubTopnQEMZtZ2gEYK1s57RTFkd0CzoyYEnv7nRgnVWsrGj/WbhGfD5Xrfe8i9K3Ree030rG9wuw==","shasum":"3f0fbf6218660d22766354be797f8256cd4c4171","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5357219.tgz","fileCount":214,"unpackedSize":2710179,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgr89qCRA9TVsSAnZWagAAaN8P/jtXLvRAtIeougBiFOI9\nXLhH856bUVBn71plmJmNl0Yfokd11p2xhlmIBIoXbYUJtiYSRhY4NiZaOQtR\nnvYmc9gV2+uSTHDfPT98hSGPLm7yH4Le7URP9g4Kmlx8wyVk7uaf1gR6LYX7\nvLvulthTH9CLHxlDSHrYpxUCPY7Z77FyGUZwpe2juQ3kxCIVIvjUYcGPqqpZ\narCXz2R9c/+G+B6oEE41t9iSUe3gSlTdVTe3kNpP2pr4xSLSJdB8vllq2Tjo\nakz6/uVX1mmJVB1CKsDd08zXq3uSaxNmXXblPBDNydgm2nX2OIFpnS4h9gDB\nCpdHWOxDxgF3f125b6gzef6c8+wAXd0+emG4jplmmeArK19vnGmC2VdPp0Ud\n6C+PLHgvm2bL+nIXGgVYHJOiztbKr29Ulow3K9y9ngDVoyBe//nCMJ2WL8Ix\nZeS6TUIHdKf2GI7WaQQcz1Nyh7mu37XXljy38o90kMZ+ZKXCdPACFi1FprP7\nLlfa8pE4fGnw7UVeV9kbwNnxodpgzxdcqfHS1sguzRK0by+qLURxEYm/KM6S\nOXWgjbpSYlnvaH92OybEr/sCIG9eQSsMN6py6JvGrrR5ybbnLWa8xYFMt6BW\npy79MR1EZw0kHPrLXgRtlP5OMgbltzKMOzjeoK+rpmyGeIXSyNXtEPtGppqb\ncVKz\r\n=n6fk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDn/HtjRvT36gOZlfh5lamyDmyg0y/BGdhEFsd0AGG26QIhAMdyhg0b9hMF0KezBtPUbuL2xfk7YPKgYoLQZUMMWtzg"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5357219_1622134633340_0.7848505814823445"},"_hasShrinkwrap":false},"5.0.5360735":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5360735","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5360735","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-zH6OozxQLRbNL4hyvqbqowCoTS2QQaksHCSCSzEqSx2lm6M+qrEqtqJCb6aKwicAk/trDlA8Pv4yboG9nlh/hg==","shasum":"d474681a26ceae001071752fc2cb92b1841e69d3","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5360735.tgz","fileCount":214,"unpackedSize":2711437,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgsNacCRA9TVsSAnZWagAARksP/jonawfJu5gu7eEZaKvp\nDNwP3agvXUee6mVsOAzV46Kcpw1FHFnQhYdQjXrwpB3g4vX+U4qMwY90pnO7\nRlLnJNzbVfYk/uLT6Nulm0s4aCqwPaAUm/e8h1rJPWL7bur9cfnbTB/wQe1Z\nXjKeYkjClOdQudDMpYPSUWFU66VuIf8kSU9GpC5lwbgDJjILD0Tizl4XgqSj\n18cx3p7MKHvSM7XXMofsI4Ijg5x3E3HU7GDgIJRsbo8y0cfy44lJvCnf/E2z\ng6dDGvP3mdBqlqNnL/dGCV5jw7QSkYpahqA0relWGtuCToJSXiqi4LflKE5v\nmejdHXg6xrIkUhvYFwdQxQyAmh7up2LGLo+2x/vqQ5PbOE9Z8J3uq/d1rTZy\n9Lo0BmtyPFLUo7w8ZrPJ85GirhCsBfVGjqNvKMkxgURsEks1bfq+DYGTkbk8\nv07ehWW5pM2vjTOAI7iPKLSjTD4+bYTvfbMvTE3mEFipoQpMtk5Y5Au/Ioc3\nRClS6tp8Ymi6DABoJxY2iiIS9iuACSZ19iT80fLvrjToxTM3dnsdVX39knjL\ndK6yIwXBs4johifnevCV7pQKY2CjQcZSrhrqYuZ+OIC9pSrQrEpuSMX4KFQa\nOmhI6MmtO2NLbTmSv2DvKQ/2SCJviHvi6LjtePnKzDOHL3DKyZ82/ONEpkba\nTDx2\r\n=s8sh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOcYAmM4zY3pbrJPV/Fo9EFoSAA7WFtXRYSXGzUGs5JgIgP3lSeNoF8O44XOZDQMPNHFmACztnmMyHK5o9wqgPDec="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5360735_1622202011766_0.8108650281408378"},"_hasShrinkwrap":false},"5.0.5363006":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5363006","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5363006","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-iJuTuOgjGHN04QYmfjeZukW4ytT9/8e2EtKtojga27ctBY+Q+HQ3A0+kaI6bpAmdxfdrM4R9o9fe0y6AjrZbKg==","shasum":"8a909e9f8f893813454cb4d29d4398a7d3e60b3e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5363006.tgz","fileCount":214,"unpackedSize":2713588,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgsRkLCRA9TVsSAnZWagAAzQAP/j3lR4zCjKwQOaDuuDit\n8DQXLFbtTfjZ0nULdF08DOiOZoBP88+CxZsXjgTyTF4UlEcSITtUZjHsgwej\n4HBm/HV8Wok1IkdtAbWfBat8Jy5aTtPYW1Yyu07fVgvbTh26pR194gWozVEg\nQTGxX90lNegh1JM7o169RX+rfdOEOLlnplPA/8FJKYjY836Nis4Nottvmtzt\nkhdg/ZEZCU0fljlJwuIY0v9TCcLc9tg+q6ixEmmSQ5gtmJT2jDlmKTet1rWj\nco69Skom7Kp2XBLbB2h3rykxMbL7bnKLmH3Efn7dtmMF/hrkn2dQ6/ohSKRG\nKjBDpctf/O2oFsEZAC/i0h4uX1Ju3jEBqOqa/b1sjiBDpiHS9N+6BnsGDUD3\nSKDm9f4UVDAVS27aeKiMKaruISwPHWVeJBiabiOSJzx4M/NwYXu3oBprRP0u\nj5jbb9Lirpk44QB3fnsWE8XisEhegippg4NUEcIOPkSE9HvEMR9hKAhrC6Xd\nX1KBNtKJLQTl5KB35rjYTwnAkY/i3zQ7MEEBJypBonZm2r+IvX055yMyl1RL\nshkZ93XkmDB1eBkq7EJeAPv7z1LULoc84+mo0N7DizDxO801xvpuyT064dcY\nYCdLZnNzqPWjmTmadrFDmFaONYj0TMkEDiPfrEdCHAt/TSyTjKRITIzpDe2x\n3Ufu\r\n=hiC4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+YK3QbyhQOh0pW0Bt9OFjxnv3QFaHFqT6oNUM2l06awIgH3HDubAmlnyZePXbFIMZhAWvHnjIXCLWlvM9ijvjXag="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5363006_1622219018973_0.1780858526238187"},"_hasShrinkwrap":false},"5.0.5386988":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5386988","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5386988","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-imDz+bG0DFrHkxuchsLpqgd62k0I/JjuvlCeF9HQwx4TCO13eHrMOrik7hbUCZaMOJcC46JKQH94VjvE2SWO1Q==","shasum":"b41d8ea76b3318581b7676b239639f50e6a72ecd","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5386988.tgz","fileCount":214,"unpackedSize":2714734,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJguRd9CRA9TVsSAnZWagAAE5oQAJv+ddGKmqWvHRGlDiKS\nlMkteu/BPWxShAwipSf/ePxCum1x2xVdRFQ4oPcjhHh+kIk4UlFyzq+dBMHN\n57CNuR0dflxdBhesUuZNi8QN85PTxEwFYIcYws2MB8Z9QTrGqqpnH2+wlMx2\nMbwQJT9j3Np2qMwfnftFfGKCgE8BQFuuHPrpFNA940QSPYOfZ1ZnyxLJGssB\noeKsp8J7UNmmHOPyBIlZ94gQc2m5Rp3NSvY8AFB7ocwghwpbXmBaYhVyGM62\n6EdAPArUn2IYPW/dBWhYVKlz1zWS6Qnut1D5IuQ8iAJIUjkX2GMOQW0V54mq\nkFPu9qfauY7E4xUWEE6hjVGQ9soEVY/uPg3pQrpQFRdKFmOE9FlNqeFTSrO6\nSQB6+cGOIFc3KcelGNUm0uDPLwajFoDPIN671p6HjH3mN/I91Ql+7hGNQlvp\nZY4syrH7vS/AHgEl+44Zh9djlfdiqvk+E55Ltb/bBqWKpztXdU1GSjaBY23T\nd/9ljYfYc08N94v8BX0zk9e05AKMaq0FaCvoQL77csLKdX6iT5DBtYw0uTU6\nTfiItjHnpwamacpgp99OhAUu4AR5EGNQFUkN9nIP750J9peCKsB2f0xXuXRZ\n0M+nrE6Ma+EX94++Tr2Y1b9ABlEJrxauB+KVEdkL/n8geE8bd4A6q7ghLIdp\nRmrR\r\n=0BEG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAP6FgSHnkp4CTFrEcUO8UyVC9MahfkKHrII2tM7aJJzAiAAzbZDBXviIC3i5LoW6nhfs5J5dEvjkDLT2VdNaNSIXg=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5386988_1622742909214_0.4390754942907491"},"_hasShrinkwrap":false},"5.0.5404269":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5404269","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5404269","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-bFtAJquNucVgvk8Xhj7mLHTiNmwBA+F2/ly+et02us+abkIdLRIDN9fBjGGBA11YHhX1yd4q3pcMDGNBODx/bQ==","shasum":"03069f7e2a9cb243f1616beee0210121def318b9","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5404269.tgz","fileCount":214,"unpackedSize":2714734,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgvyaTCRA9TVsSAnZWagAAezwQAJD5clZs51l/WSKRWSfL\nZFI/7lnAV9Cfck7q6Pbtt+553bNVlIPRAV48x8DbvNg2l4VdWWqZPe5/ClUe\nqZKBVUiGeakuIQB+jvwI9gM4wjK8In+RhH7kgcjsOxIztU3TdWN+GeFCE6Ey\n+Ga1e0DUkVcOvfsO0PgG+98ixwMywDHdUOkJBKI/Fg324zXFfwk0sgA0CKVc\nZOPvHUbOrQRUHCfY+RSiY8QkXtYQGZeUHHPo8i7Yk88xJlUDaa/zqwyicZRq\nG59WQ+8htvUJ+F3Ci7UJH4DzRkMICaY8GaT9QqH6LjVTyjtGKzMQMzEaRFpt\njH6MmekKaIX1Cri1XboMpzww1D0TSvgQfY09o6rjGigtzbJ0D2ktQ70YOi0T\nwk+ktcXgPRxmAB9CkcqgqJ4B6yvy2wPwgVVSlJ69S1sF+Dwo6FbfQc2emmDf\noDANVdIVyG+tO9G7RkcThPb8VWJD6sltKMVU/CA5yp5VNEj9xlJ4h/T4gSpo\nZgBoNyOTjnBXYGg/D0ko8+la63tdMs6qivBMVdO9ZeKqZB0U0Q3mQ/z9laqo\naGu7GevNgWgmUNK9URipshzCTH75hnD5SPVR6BOTLQPt+IrQKq34QDyokdGj\nOFF00Ahj+3oKz2xAuJV0xcmEIt9BmUOtxzMX2j/2onnufQPj/Mz6rXZAuf4j\nvygr\r\n=VzP8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCS/SuN9me20k6bzrU+AmK6PZyItoEgiiOZqiNK9jwstAIhAOSRQeizxDj4M6oPxzkSgMNAC4dRmLqRJ57WUvuWcjy/"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5404269_1623139987744_0.3383108192712303"},"_hasShrinkwrap":false},"5.0.5417264":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5417264","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5417264","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-N46JCQByqmsZtjIm7N/slHzX3zxdz495lMmWcvAARasFQY1xSRorcLbPWrutMWx7hOekTH3XgCj3moaxlSv8Sg==","shasum":"f63ef988e340d4cc169fe03d07df8b475bd8f4af","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5417264.tgz","fileCount":214,"unpackedSize":2708954,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgwLJzCRA9TVsSAnZWagAA1iEQAJnVv22G7uj4QYztFd+6\ntCv8krC4lk0DTOzPkG0Qt+FBCRuI9HfMXbvSp2xefjjum40Gkn2pls915uXw\n3FUkAx0F4/lfQEp18T0J5/jBaigwUBBXF5I1ivMw0Pti4ucLqekbdxX6KKfM\nwZ5rhCjyRYAsTKjsom8XidpnUpb7PGgmjA83R2CK5ZX88BRIDiFJPKJmGgbh\nig6wqP8zZBMLjhiIh9fSpPmdXfawHNX5Gu2yNy6uP280IcnbB7Ph3BbKMF4o\nKCmErak+3GRa/QSJEqU3juCbmiJPt32YUm/6vFWJUhnxifF+EtyMFFZAtXla\nZXBavL2vgiZ22iv1cVgoYVxqpu23bxZlN7xjY6CN2eS/g7l+AHcSGitRMxUE\neSa+SW7B0soiFWCypvo45O3WjgfspaLfOBbXrz15NJi6hLTWWf334MN8xQT+\neK4Gsim+vJV5+q7lbikH+GF59FKIfKRq/zk8Ed6scyLWSq5/Ydr+bDy3Hi86\n3wO/ot327IgBDdi87Bau/T2RBgUAjV4dG/ueSZaqd321MyeAKmhCA17izs8T\nJKqZYuZM6LMTG3P4bbh51C2qYfwSxZlVVTrDGGtJhnKC9qKDc8fotj9YL6JO\nVBNpOr4cceWago65DgJZ6HVW90AM5fCy52/c4nXBRzwEfYDNgG42OLH0xFOc\n2CBH\r\n=3R4R\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCxQ8hhDo8PwD9sc56/3N+sIVVt5NeKm/Mu6gPmskZJfwIhAM0/5YTRqi0eNjslplSCtsAA8pWgSGqtRjFCpIZ3Idfw"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5417264_1623241331254_0.24300935479391406"},"_hasShrinkwrap":false},"5.0.5417268":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5417268","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5417268","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-d57x3uvRLbeUtsDIGvHmT8Z2oQm8/SQ4OHlZHRIdds2G0Y0UWinc4ViHgENEDa5HTxI6RAWRcMNWYx0p3Wvz5Q==","shasum":"75e684d4945e258696433d2ff803c008e37a3f11","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5417268.tgz","fileCount":214,"unpackedSize":2696874,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgwLMNCRA9TVsSAnZWagAAZEsP/13zBRHoRbBeucu4FHfB\nAINrx/Y1xU9SWaGLS/7ExcNlS74N2Y/r1wi2+r8S8LseIKGGzHTaYeakqttp\nlc6V/QtwvHjmEQminyahhY4p8aiP3MJjc9C+XR+nlGcplABWlZG5+SOe9OvW\n9x5LkHKLc4HmfgkjSrhXxYPCUpXCXWeg5BYGx5BuDu1zUiwp3y10Xx0oOvIL\nllCNBX6OagtP9oUSUzjoqTyOyMMTVZjjf3oT1ZXYIlP31mn9dgXaz47YRrgX\nfnK8jy4kfzioNrAs/SBruLE9vCiLNQ7ygF8wonkSuSka81ztX9lAzggEjrZD\nPqIyx+NDBYWcGaz8YsHEQS2od9NYcutghDFkBHoKZd81k4TwC8nix1M1pyaP\nu/zAmLo6EZwakjMCFJN7EY6aDUCzUJbrUu35pycV0mi6rjyy8QXcnYisVncs\nmFYR+QA+gKlXGmwKKqnAI5v4cP4sFqqDQNZhH6egBmrn6u97Oab/6T4GleE3\nrjndihg7dChsEgT6fq8MkOz0lqFgiSXTCnzQjjiTV7ut1MB133KFmbAn1p/j\nACLVGSdLr+odYkY4DnO1NF2Co5RTuz3fiP4MmYMbU7fTJfkuNukoMEqkiHG2\nT1mHwFeq8yrz/AnqZ0S+eAxfQ1jUYd1pZj9FMfGmoIajK+zAAOnVufwvQMcn\ndbmg\r\n=AvDe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEuLMF2pbtW8ZVnnNS+i8QAFuI97FnYqLsrIm0x5hWKVAiEA1hnaW6NWaD0xIKUAipMmtnBD7JrLghMGtUU+xsD3lAQ="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5417268_1623241485661_0.7220413306707738"},"_hasShrinkwrap":false},"5.0.5417588":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5417588","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5417588","_nodeVersion":"12.22.1","_npmVersion":"6.14.12","dist":{"integrity":"sha512-RE/eriETbzl5yPOL/MzQ3SDa2l8pZ8dCzP8NJqvMIwou15DeP1YJT/eG0O9paYQBPwAlsVBHLC+/PL04Sqnc1g==","shasum":"f76aa3462acf35cf95599499d85e89db2ccbb303","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5417588.tgz","fileCount":214,"unpackedSize":2705022,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgwL3fCRA9TVsSAnZWagAA/4AP+gJynYJ0HWla6L4S+qps\n9YfTsRBD7ug2XO9Vm1SoSbtBBRR+R3OzSIpazV4fh6o6PcqPP4DXPepdwWfU\nqStaPYW0DFAq1yJBwgQtC9Gc8kjAQfvMFTHBiPrtcyE6YMEBhnab09dt/Ae0\nBneauz/xLXWByZpkHp8heHzMt9ohzxZGLnGHxtwcWOPx4uOlQ46/RxNhqKHQ\n3aqbdpF0CH/wnT4YFvYgqznYI5GYuY/oCyEK5JHAN/oGw2MjFFJgXOL4543Z\neWu11gYSSfgo9boJMe5PC8O0h+tf/3ugUfe3UlaSAgeHov6oUtaM0F/+VfSP\nPtwR34g1kzSkoB8q3ODH+2H9dKBZGFAINAC6Gn6Ap1Oj2JRSJ9dKvKeqId0r\naXLr46KGqXQ7cD4R0UyybsAlWzNFMFgDx4R6OJTy/FtLeMaB96BKPShV1Zcf\nMY7l62KbmplaqG1kXvg5awtBGclplQP+6pSJV9f3zaql57CcKC4E4evh+4c7\nOFQmKeT1aE2EJIa1EwMBdtoOVdRd+kgKiTpOASFhv2eWmX0NfoPauL14U4Uf\njqkPYY52MNR32qMFEUIdZjMM9o9t1H2XFYy8olFbDCet/YfXKCaR6nYn8zOb\n9WInlawO3ydP+Kh9d1vk49pZ0q1yI/JMbbfYU+JNs4N7LyHoinAtiCmvt/Y6\n9OCb\r\n=fbxC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEC2OxC/N4hitSZjusChRugR+vkDP5qccQRnBLbMG2xjAiAph6BMMcJ5RfK8VtR53lmK1qpVlunANnyRZ22i5Tblyw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5417588_1623244254836_0.7981257162399955"},"_hasShrinkwrap":false},"5.0.5596806":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5596806","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5596806","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-owGimvCV0k2DKIJ1itk/W2XqqyAizOouLi4ewecEEYxvY9fVkYwjcH2A9Drg2uYfaNNcs5d3tUEZN85i3z65Yg==","shasum":"d7414c2bfcfff7127dcb42326f89eaa1d04bac09","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5596806.tgz","fileCount":214,"unpackedSize":2695788,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg7BRlCRA9TVsSAnZWagAAk3EP/iYZVeEmJ2V0UKOejSXN\n5eyxqoDLJur1rLuunn52RGAMbKWNY+aoxRV+30IZUafPtPB5jIHkRIH0YOMW\nOWNWrmj8g9lblT+ITYt+dDHzPqXu/gBqy3xrsrsB/7Cs4QWjniY6d/wI0fga\nMFW7bMZ2HK6PEAlqALHhYg4p0wk4d8JCWyc3ZSaInOvOb3/UonehCLKfCoAg\nI4fM5PvHZ0RvcrysSAaWjE3DFIhUMeYh8NS5aVL1NbpwBQ1wpxd8xSyoeBVa\nFE8ZznEE/Ocfu4ogx5dyqRMLD+jfNJWDw6XChnrh+LV8lQE9i8ptoS93dOw0\nyUF8m5dXONKwMO+qCvL47qfQgWJ9IeJxdUjKt/IiRqdKjQhhbl2XYI9CncdT\ns2Q5eXx2jN1BAek/kwTSkM7gDCUl6a06wBLPiKaSDKcWsB0p+Vc9zVX1jgrf\nGXAiId/pJAfIFku/OR8p3yOf4RX8WoJ241C55WxzjAVsDWb4rHO124D3meBX\n7o3z4e4XCeATIcPD71+5bP4BZXzThKOCe3pAxj2elPM86GkXlSiNePtlPREZ\nb/qe5pLN2Zy8MNBVyxT29BAySw8vFc6YDvKxjz20NpVnDZ+nhIDaqhNb1Vah\nqxL3HJYWBNO0dHwu+EWYfXXzkAzp9twmBHq6GCTfKMCTxGbMWZTkk56dN1pW\noiol\r\n=m3iP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFE6hcjxTx7mDcpvHlCNpeMjmfkNG9t2zRL8AkVPpa6FAiAWWhVO9X4K+EeIP/RMCZtHFaAn3I+kwJtVUa5JqXjLPQ=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5596806_1626084453175_0.046220935045833134"},"_hasShrinkwrap":false},"5.0.5605714":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5605714","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5605714","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-urTKTZPcy0ttbWeoEmQLbkruyp2FeYN6QV8GQsY1AcRO0Z/662MdSpsHRcl7gPPtGW9vVqnhBTellE2CVNPcZg==","shasum":"382df81f42be16ead622f354751dfe0162c681ae","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5605714.tgz","fileCount":241,"unpackedSize":2699035,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg7W8aCRA9TVsSAnZWagAAxwIP/0htqxiKczcIMkfXMJVA\nrpWyjG1ZjQ9TcWwcpRjT45uzw1zOUMpzlG02rqIWWMXYfrKPgPpGdHCEKihA\n+kcwXRkYn55rHl8fRfOvd4DtDL8MdYCHGy18sD2Y1dV0i93AjV7yXN14+tO1\nqUBi6bs5oeOy2hqbySU/V4Im2AlnKwN3oR7Wn0ZVWqQyy0GK3crUKoh94PuY\nKBSI4X9mqN/Hy82fee394+AfhWrVqHBiR8y/kyddvZdCgv952TWYhgPGG3dX\nhZKVEKmyFNK8/pYPMdnzIYRvU27tKrkeKzixwBAp8iexJS6kcDp0enWS9Yl4\nVXY+/vAyyIDA/0lGiooyfrY6i4c7b9UEcVZTaOlZQQN0b3IDjCcS7D63HeYg\nfoMdnJs+K8/4x+BbUy1AWK/fMBXV1l684jwo02jJV20W3KjP1RgCYaBhZNZI\npeIydVTpubhB3Ahz3YHGmxTyUgRyiRH1J6/OAg1rny+x2zNNmd/GFVYMQoy1\nAXdmJ4+f/Bp94ZNdn6TQ97t+6yAJxxwYyPZ9kRv5o/JLVf8hNmxw45I1LFL/\nIzGK3BO7eeNa5/kdbhxBc9RKWTzhCRJ6yJdC5rcJwNiENPp/ZQpZhH9nZwwI\nQbRVNyjyOp6rECIARLelh0Bf/PfzG452fjwti25eaObwTcqKGeR7DQGxf+af\nOrqJ\r\n=HR4x\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDjHa0KTh/Tm1E0c5ebpr8nI/di32fbmd0Tubk7DkLiBwIgOVWxq42zSqhEMinT8M+H4xPDKJwwhMW91D45ZcoMmMU="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5605714_1626173210304_0.48518466433359064"},"_hasShrinkwrap":false},"5.0.5605910":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.0.5605910","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.1.3","aws-sdk":"^2.610.0","axios":"^0.21.1","cross-fetch":"^3.0.5","fdir":"^5.0.0","fs-extra":"^8.1.0","fs-inspect":"^1.0.0","graphql":"^14.6.0","graphql-tag":"^2.11.0","immutable":"^4.0.0-rc.12","proxy-agent":"^4.0.1","rxjs":"^6.3.1","socket.io-client":"^2.3.0","sqlite":"^4.0.19","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.0.5605910","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-NC8O7o+82dI1dkQuK0nbx1eFF61ECFcyyQpYs+nk1IN9vsTIZCwO8y9U/joP7D/4dWO5ZZ0Gi7179SbO3GDwdw==","shasum":"1a6e739ec9a1292151e8a7da6e2bd66e27594919","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.0.5605910.tgz","fileCount":241,"unpackedSize":2716546,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg7XEACRA9TVsSAnZWagAAaWEP/2G4O2g5luLhGAy79rPO\nWxVe+6hagLG1VycoAlSku5pdzPVugOEyO7aZ5jwwA5nhrrfGXGwqK8Ze9hS5\n3gbn6iHjeQlnyen1G4O/byduXz1dxX17LdevFmLSv1t8tnMc+3cKywbxIR43\nUk9D4uIYPxhqNO+k4TIpOsMeZYd4O0b47gTLcDmYrqTKj5NQMRwNBLNu4tvq\nhYQNtnK0VRbpuPXKu4nwQlccTcOALFdSIBR28hMU4+BZkWT07YEwVHtxJ2Hp\nMChzbKotpRP/IP32GO3bvyw/pzpy2pR6MFpk+STzCN3CZvTsywJIYpIn4diR\nWIa5U9BkF2u78yecmZb0cXLOl9EAz06VIm9O6f3Un95VRGl6LHwVwixPLS8m\nre8ygId6fi0zSzedplmtRB4C0Em9I9OJ4T1X+MgUKf92xUPwRYyuM4/6YKpc\n54u1Mm5dgiQJSFxjjbIH62Bpz05NSeFA7V2W+eL3UsXqkS4TlL7La/F/XI1w\nKc95MH1Xu3dmUlsJoOR2DHJOlSKwoHvrzTYTmo/tdhORIqFZ09OOgifmPogN\nHQq67kGV0DA3zUY4n2pmDLgmCpHMh7wKya++l1qmfyc4UfjafRQqmwjghe32\n8buWPVDxrgU/0TUxKzdiNwurz08qoFSf3f1F9+0yIIby+FhenVV6j/HC2y/N\nYewm\r\n=eL1W\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFq5J7cFKaFZWYPIxpuZfv1OIzjScEYo75SfLtPpSaBKAiEAx4Sr+EQmSIaJfKc08VNcIxnS3vOC2mfFtvvDmBZ8l6M="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.0.5605910_1626173695941_0.8838852610354364"},"_hasShrinkwrap":false},"5.1.5612995":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5612995","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":"^6.6.7","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5612995","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-X3kQtNbfiZTdem+Qv3iiYEHfLnX/1oQy05cDl3Ne/1vWU9VCiI8hxGlkFryk+X53LRJKeyzBX420ThYM6OyFkQ==","shasum":"d4d529b1b21d22d7a43e81eddd6cfff46f5fe385","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5612995.tgz","fileCount":241,"unpackedSize":3275210,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg7uX/CRA9TVsSAnZWagAAsgcQAJDnkKqvaVtDes8aF7xu\nqDWYlbHuWnXTuo/tYMCYhfkhpGljhXu5mQkXDTkddyFVFeMlR2UNa8oKb/xy\nKDM0zuH9sqqw7SecJrGKT4grJWdVuODypdJeqmE/dJjoHDUGT24Nt5wsFl6F\njA7PoKps4OqJOkR/XUG5W0JN/5cxMnXZKcLylcxoxsysmHsJ87dVmTEv+zdA\nmkwLbdIiYpojB3mgE+3tFfbG/u7FvlIf/dpU7+1lx6jY3g39DdgiUPBbMStE\n+mWcTWPzMyBtSU5KVuRUppW9xWR+1y/2fLSsQB5cSwzhstYXtoMQJDCVaPlp\nr/1I3LRX4B+FB0oCDV1l+BCJPiR3mqGGqGtKbx37N+J63xsZ7K05jDAhpLw8\n9iT41MSTc5CmXRKtT2TRIipDKUc53S3ZBHGZjkIt7xv0V8l5mXHsT+AvFfNW\n/wa2yKP9zBqkEksfEQ2WWUuFIpN/Jtxra2YjePmPT5yLmMe8/IhB+xpr20jH\nXmdSB1z/626Rsy/6zt3kOfVN/vrOb4iyXPHtPH7omwmc/fTk4DAVFzNN8DOQ\njqaVNwawMwLX6abKuOfmAtQAiNP7bJe9UtfKMMXdn2XpPwTm6vaup9F945vg\nFeWP7CW8BVMNaFKp7TAGIMoooyKO7L8rJzyOUDKxrcaibIrxX+/PRFX1zBCl\nqNWd\r\n=J0XI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCJUDLQ72MOTUKp3ztQMP2qQvzLRi0gVL/l20LjCFebngIhAKhHsbDK+7bX6Esix6ZeKBlu8aQVNIISBg6g0KvTL9kO"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5612995_1626269183169_0.13299220974535464"},"_hasShrinkwrap":false},"5.1.5622563":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5622563","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":"^6.6.7","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5622563","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-6UJ1HUoU9g5ZUTcfO+vHeT8PJrN9yvrUEoIeVG8geJqsoXjOkdetpSOliCOJdEMsQVrEj7CXahtnOxzPBrcmwQ==","shasum":"e2dbceec47eb046edfc62ef66e09d34e32a77aa8","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5622563.tgz","fileCount":241,"unpackedSize":3277154,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg8UNgCRA9TVsSAnZWagAAHp8P/3VUwGUbO4X9EOrgnWF/\n40isBpbTL3Z2SQXxy2y8cKc5CDNoJCELiARBsthJqlV7LZ9G+/sNS8sHDiUA\ntYu4JlmEZ2V7F8wPg4r23/o8A7fO8mMRpLXHGCtfkQD3rm1lpKBkJhYNmYuM\n+lNwQKNTiX4zg68A0214GXfDCHJkukpnQdfYIA9WNv7hpnDlCr1MGBGjnfD1\n7khRjl5kTRe/0ql5vjJ8USlWy39otwkTZH7SPuBrGs9rkLEHX+gir0EB5+ng\nwbdWpZPkfQSlxFjSe1ZISOCUprolTFdvt+WGxhr5Q87BD75xDcwIqEdlgOlp\nl5quTA7IurlXFFQi5+1+1hLm0ZWWj/xOxRWRmFIi81InkxluapubpSAimDdO\nGltCG/df8AjmyvBCijbWqArEnlPpxb1lW5rGuXRQVczOY+QibDBHzgIqbCM/\nHnQZ/9kJb8CU99XyxVUIR7l2b2ZILIAlK+GfNeNUh2E7+f1kH9ZRPRfzXCh4\nJYHgCWIOxIHEl/+ig8g/1rUdk4OEn32v8TYpumkdG649ZVw4xvxZ/yAVdaym\npfExbS6g+kXjhhg4N6TqSk+8RJpQdN02hQf24dlbH71ZpyPFDKi6yXzgVbkc\n0uMrylhxPTCR90Eil9RFYyea6vWNOD0Hq3kufioWQhCQe8K1r4fz/M0d6gVy\n2jXc\r\n=J557\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCAU+cPNq+7M7CJazsKOwLNK/cAaMTpkU01AO5bP2jiuwIhAPdvoCCvTkz6uyl0AUM+lWjfdO1j3cSCtiIogdvUoAZr"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5622563_1626424160699_0.9989021777185823"},"_hasShrinkwrap":false},"5.1.5624711":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5624711","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":"^6.6.7","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5624711","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-qDgDp7Gk48HNI1pPTTVPJkoaCQh7wyYwUoObVFXTDv7Sl2mEwVWotDkltf3vkkPG2ewMwHYGTMx/IsumHCP0dQ==","shasum":"05239e1154859d070ee2cc6fcb7b991a81760182","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5624711.tgz","fileCount":241,"unpackedSize":3277485,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg8Y35CRA9TVsSAnZWagAAtVgP/1wHeEPS24QHqDxLcU5F\nH94FMTjDUlCXMcq1FmfDtKQCjgD8DGocp5l267T2H/jxz4LMF9KgV1UYLxqO\n3kdWiudUcuadE4qraq76S45bZ62cCzc7M28Y5ZHFHK4eFZb4We2yoykBmss0\nvA7Q6yMlgVcQEwJtPWbKP0LwP9fjghQUYmQFupeei4JdPksH3Gh4mRSorEje\nQxSvPZUQbpapRJ3P6Se0v0iVotMoTH+mmSx9NoTaE+ZQEbtKVO0HGi0iDA9Z\nBq1Pf6m2FnLBfr4+xneKHh9zFBtyKfc1Q91WqTWeyp7UgnvEzyiq6CEN9dR4\nufgGWdBHU2WaS0qCoL1pFf3hiKH8t8S95tfK735ixebCFWK1O1r+DT1LkNLy\n9g1XzTbSa2JFiK3IozejRJaB+UcVch3/6PjrJwAcWOAseYynQJN91KXq+gki\nhnRK5DwaVHMZMM5foTsVZ6dzRTzAf8BtOsUlomHVnkATaLuWuk0gQgcHVNJD\nIoM9PdLw43Yl2kXHjWdrNbsOaEd/5RgX56h8qduu2IGovbWzRxmzvIKsnlsR\naiCjbytrRcDsh8AGJVJZTNygMJz2QgVfm+gcNTw84a+vtO9zbnsY/K0sL0i9\n3naebx/5raXQFO9TSEad4SAy4W8SbC5MScxKQgHdIapDxO43dBlUgHLKmLbC\ngIpv\r\n=MGpq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBbrdBmiDaiTUsJSx7S80Q2/ldB5AEurJb4g6nPTKgAXAiEA8WBgAZsH7Jt3a5UPUNehAdpr4imhfhZ2DrQn640SmPs="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5624711_1626443257733_0.3071811598395757"},"_hasShrinkwrap":false},"5.1.5638463":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5638463","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":"^6.6.7","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5638463","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-I3AaeP3dja2GSYaJ10xxwJcoZISuovErMbIWKtcrus3SVfoYC/MUrz2nVP89dDQISunrpLDsMmhE0Lb5VUGrbQ==","shasum":"aa60ebe088d4140668fdb3db04c9e14fcdb9633b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5638463.tgz","fileCount":241,"unpackedSize":3275924,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9rICCRA9TVsSAnZWagAAxQwP/1PJHYezL4F5rlq/B9OM\nkkzCS6NdMwvB2S3tnu83EE2R2xvW9UgCJVR0BicnzbHXg+tr8QYa8r4OUbPY\n7xqykxbqvImGXOWf5M9zz1/a0FMY1CaF+ImfwInpoVUBZVu1KWXGvKJjVMpx\npbHN8cCBAj55/wAophI5WVmIbkSOFNlXJl+FQ7EcUrJUAU/d4HNdALfuyjjS\n1ep8B9UwFXjzRF4jiNnPsO+FliG78GqzmYo4YhPk1ciLFJF3G86LKk37am71\nP7vf36PLtlwtsXbuwDovu7BKr0sJSQ3bAXcj10EdWjHK26iQOgPep63Vu4vs\nbPXlOsnKMpJpqQwKmjuErBx5BqJ6pfrJ7SKu31qqWDLxBXBJh8Fn8BTTPAU+\nS1sZ/CWQRxRw4caLRbaUxJrrMoKKYeDFzApJ5ltK4nNw3Ba265WQB3TSDPAn\nJFkGvAd6MQeUTNRKtzKw2VsS9yU/OH/UryD8J95D1iA+QdsVSqM9rohFwYLS\n7h68tIA0Pioe3R63lxpA7+ai8tZhmSossGk98+MaN4owJcdEpD+cQAmbnMfu\nRZSXmxU+DKpdvkmDI2hDltZP4rbghh+uDkOL7Lbz5p42G9oQCJjEDMSwQH4m\nqbk4fLaaInI4PQmbCORpP87KVmfqBZoeHADXhEp6RXhMIWsc47gR0puXbLad\nQMmT\r\n=wZFT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDIG5mTeDEAHfPA2BOiuUBBQolgEKy1U/9W4UMzhd21oAiBEc6TnXMgQCtVbREAW9yo1IWBk9v3QJiwSyptXudkWqA=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5638463_1626780162573_0.6537064646427058"},"_hasShrinkwrap":false},"5.1.5638553":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5638553","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5638553","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-JOHmBaAjXeYXuKa4FKbv/0HcpN8aMPaVRrUIm451ZW7nkh0X9+5O5AU2zkLBtbpLBpzj7rd1GBzkLs0ETx5TSw==","shasum":"651077a6aeaf2ba39751d2380bd81657ea75d667","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5638553.tgz","fileCount":250,"unpackedSize":3304566,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9rcQCRA9TVsSAnZWagAA+u4P/RdpKFo+nhavpumFtw2E\nJGzPu31N41kcedan7EiJYxPVPFYm/Iu3ykClhe37r5HcdY0CHOso+/mD3Qjf\n1xmQJ8uRBYDa3UvENpowqS3vq8FeWfyNWbnQ0aVcXSjzbNKIfF1WB73W71Q3\nCKUTp8byLXz2g8TWM+TdAmeex7x/xkYbmbMw3YX7nMD7v3m9kIEBMW2GBGZF\npqO7TmIOVro7I+iTGezyrmt9F6jdRAa1dZI/oLtPZZhH84boQczOyVfAfH4l\nzebkchKM/W7WDVzCNKEWtvntzn84EWQh5V1+XbNIUVUfB8fPYEJ5wzW1/ntL\nO2SZdI/GyjQMtPV1wfOyb13lXlSEmXbVOW1ot+cjq+47OEIt4rgrjZ5DBlsZ\n9RFxcZm56eWHbJjSn9bjxXivLcbXOe79zhlH/YBxamJTbGz6SluiJ9vuY9bz\ntE3JnN0u/MYYwxlHxpN8pP4+qHVhUQnZX6TjhniS/HZ9+ASaxuvWewqF+VUs\ntEPs0Afn0Bzt2vlMOXgeD5Ddu2m3GW7YbnRx4cj90JAkERRiDzprtVHnsolK\n1CMNhKqg+GTBGIvCBS1cH16Joujt5v8ew+EaW4guxgz5U5N5QTk+QxvCQqgu\nvQBhiuS1xmpErMQPrnnnaRKEJEm8OJKBK4YK+UMCptgT6SNCWpX5lyf4lwgc\nxoAQ\r\n=VowY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFNEWe8S1wTXah5SgzqcExEvurk4wQ2uRnvShwFR+RgqAiEAr1XCm9IxplwDu9x+TQkGYYs0d+xJKzFg94JD3sL7r4s="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5638553_1626781456470_0.9280235562791452"},"_hasShrinkwrap":false},"5.1.5641372":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5641372","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5641372","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-DhrLRzy9ZFN/H15Eo3IA5Q67ZTrp8+jKU/G8kVCFYb+0LAo3g2XjGE9yjYq7/fG7o5lGK+/YS0sNA+L6lVSjVw==","shasum":"6af2869034f293678cbcd6c2d796335daeb5d958","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5641372.tgz","fileCount":250,"unpackedSize":3302853,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9wNtCRA9TVsSAnZWagAAkasP/2gQTZSxJVS/zn3w4/D2\nV89g9CGsXWidxJFF6eTTqoRU/6U0Ss9X6UWjpRvyd5+s0qDoPWIb/juRXIjf\nY7+DgOoYkCRfXs/synhyFocNagOQvQBM8Pgj3MDthgKV3N0RUdM/VylZ1PoT\nlEKVmcaOP3ckyTC6NpAsQWzMYX8ZkpyHfEqTN5x/HLAllDk3Wk4JgN6FE9Xb\n5haPfsiBDRMYDWWZxNfj64o3unejkpi/M399cwYnxcr/S4v9vTi8nuxwtotH\nFRRSjgTtyO9e3xEb6mUy8rlkj6Q53Nw/nBi6/u5iPB/3eAZdf3ZyKQ0acAaL\nFEzu2E3EaHb1AgxLZU6Dso8mMt9c/NqMb6rZfOUi+AfDrrZ6NtptGZD6/jFN\nxF23Wh+fMcvEBtybxqwfYM5ov5ZNABnnGWLikQf/Qwpouszh61+FkS3Ych9z\n/6y6eBgVuEp3O8lfGwTvxc63bIJ+z8nM5/fjOWGbJZ8ko8+J7GuHmgidSxCo\n3NHky84JJXa9s9lROcpusQOerucdpE93SkO7FDSzSvUmK8rXvfF1rluPpxYX\nL6heopF0LdaVxF3bXSDBui5Jq193S9/KxTtqQdwrGzwUti7dzlVzy+sHSQt8\nqnGxY3Av5ASvaZdmcZv/AqwR49nWnK3rLGCXQyZ9x0YFLrVCx5FgDuMwhkt+\n/MiL\r\n=4Mjw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDUhL+0MZCjEyP07weFRt/MOtcJjdNPDqjwp9l2OY8FagIhAObn99DQIfxXu3txQNIkixloMlpnj8/Mzm627rZ3tprp"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5641372_1626801005475_0.0273869937027027"},"_hasShrinkwrap":false},"5.1.5641422":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5641422","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5641422","_nodeVersion":"12.22.2","_npmVersion":"6.14.13","dist":{"integrity":"sha512-jxsRz+lpEoJTuYbieyxjiP9SMxy6NwsCP1/OVP4x/10i4/XSLe9EDKd4AZxAjGD1gN9k6mwbQLIdyfpWDiTCjg==","shasum":"1621054f5b246210291a068dc7a8fc429da49a61","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5641422.tgz","fileCount":250,"unpackedSize":3302853,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9wb+CRA9TVsSAnZWagAA9fQP/iBaIKrHjNqD5Q2itQjJ\n/BSg2Q5Z+yhfJAtwJl1bMyst6doAfEZFIzWrDrJoh4dalzMWiLRBzy3Ys4zF\nztpdjifBB65GBwWkvMRP0gU6KsdlmIAVeGR6o0XlVBQUvLOHXv0A0BDHjJAa\n6mBkvlHFK7AWRtSVA3uWnNsg5DGJ2r+0KoWZt0ssZi/mqfQqPVkVSf53V97f\nOWYyVffOd1qCqblnUKHa4Brwkji+dhEAWO/73cPmoyjjxeHZsD21A2s9jfFv\nkYUgTRHhappZl9O8MHLQ9naJ6hzkd67CxPGHzDP+J/C9JSKQjxYgjIgB+G2h\nqxDbU9Ddy1REGD4LFPk5KgT/A9mPp5UiUMBDuAUp3ZfuNyI9hEMJ36Df7gv+\nIpwMFeFKgl9aBJmJnWJwvEFm+vHzkvMKk7E3yNeQci8OUZ+Z1O47ErbRSoFp\n6TEIalZNUlreADD4wp7W+3gw4XIeovOPUI5Ik6vOl3HvJcGv3yd7pcTQDHh4\nAMykZpPd9/VT7skyGyiLLcAXPkdQcHvnYXEPc+G8LA+n+vLbiWV8rUO2E8/4\nX7h/e2Stj0TUuhoSfhwZSq+QrHCajLV5/lxmFTomtYNBnTneXslDzvTTbQj6\nrQS3Xu/xwmtKY+u1UYIcrwyxYz5yPPqYEQEngBnskjDBnj0Cm8tz1CY5/zbF\ntMv+\r\n=u7R6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDB7d0Cwtk+VAdIlsm0aX2vlvYznfMFKseROVOUhBV5YQIgdT+kNsDBXRuMBvpaJ/qtkdYo9xRAEpa6vYmi6hMBcX4="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5641422_1626801918180_0.6116385004608069"},"_hasShrinkwrap":false},"5.1.5691392":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5691392","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5691392","_nodeVersion":"12.22.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-nVJVEBMaOskrbI6Prk3iuRwotgnZfBtAkaShYK+42lLhuUEzY2cqF2T73ZEOgVUIWwo/+NgF8VPK1iBZoqS5Tw==","shasum":"7190a08315800128df7cd35f54774a3456777489","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5691392.tgz","fileCount":250,"unpackedSize":3306475,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhBAkuCRA9TVsSAnZWagAAzFwQAJ8RTHaSWQpj8gAL29Dj\nHfunTr8u0gEm6F4tIDzeWu4PCJOAVIjVcifiTTf0YlHjZCU++lkruoYecNt4\n8r3v5CJXVTkWKzbHr3kgcXNfnt9OrfoM79IGF4PKaz4zxbV5pJs3hDIx3LPR\nmZLwyfegidxVF9Ss+1nGj7afF9T2r+dDuulV4pfJRaGn7JOFA8LsV1aivBit\n4QYBI7WtMNMVFPUh92aUCM130q6kfUjU0ssUuafpN1QT1jtEFuK3O61IK5XQ\nQcYJUEtbW8TCzLvtQLIAKTXY3y2JV9qKAPF0Ako9ZBsIz6UR4q66wdUjEsmA\nhSDmaXHbRincAg6Ryq8jNuQ2NlYiKkzXX7mRI7bTSXWocrNo18ypWUXRPSfD\nVpRmkNX2h5hODROljDhCBcaGynufMfx8Qebp11X6U3FgWCSxzcK8e6PGFeUu\nzS/vmTuI1Y4OS19GAWGQp4IW4yqmTMEPKb8G67eGz2g9LfMbuZFraFON14BI\nANyf59edODS7vfyWlIs3ciDJ67UIOPiA6e7y7d8sqDbVg4GuiwB+wFDc0E6t\nRJW8Dkpr0mshhYnK4Cq3Eyv2tKjyIs26MLU1Hq4rEsQkb8WQFAXMExziJVmH\nuJ5HxL2H2wA7kCFd+NvEIejwYM0i9KGp1lmKEzgw3FzBcw46l/TCH3zOmz0L\neUnE\r\n=EFkE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC12dLDKZI7p+UvOHlZsEVSSAHgLwigt4rllrggEqFaAAIgbxftn24G+EwcB28Ky5A+hSDmAqrwjv+bYvWG6cM7C2o="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5691392_1627654445961_0.8445112695237245"},"_hasShrinkwrap":false},"5.1.5709981":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5709981","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5709981","_nodeVersion":"12.22.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-71Y2gCQ/zfjxW/raqz0fDT/ZjqVp2xsRS6weDI86UhPgLMuFlUSwmQNoYlr2NgPZP+dd0co/JLZdrqc+GyZVRg==","shasum":"e39120dbfc29702a7a4775caa279011e14776279","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5709981.tgz","fileCount":250,"unpackedSize":3302785,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhClw+CRA9TVsSAnZWagAAkIAP/RzEO2aN1N8y1w+Mw8hB\nccdwM35y0AEQR40ZmIJx5R7hKrySTJP411z/wV29cW7+Pjbhct8p5kTk1UdJ\n/IhnykVv80f7qCXEyksh/KzeefWvXjppgesMhXdEc4e9X65n82ozwWC6OrDK\nw+3id/lEQy5rRHIhSouqcgvFgz5U/+oAvMAMa0ce7RdcMjXq54TAAJPAPgE3\nyaJ0RNnAarWUs1WBx90RU2zVwbftUQInleA3R/wHUThD2se5XmRq15Q1n4hv\n1qRpG/rGOONmwugZjZY/ydNB1iHuDdEbZZGtJCcrwcM/8W+eHa1uGAfUcMcL\nE46Z8WASU2aHp+WIhOZMTVlgtTDY7QJeR5xy0TYpa5mSxasW2iYOtSnN9C4u\n4zAwrrG2n4eS/m0OdfP7roRwzC0AtVSwEDA5l9BOTiDhT6pm+1J0k6J3FYBY\nGUIgs4GtU2fWp20ro1leqYRlh2LRNHA4nN6i+z5ZsHXdXh1D2B8lqioa/gme\npVjsOEZ0tc2kWJD1+rW6zGpm619oPB9SU5bFOJz+CltRj8kdakSechJpKTjN\nzPwQnj1Q6qDG8DEyVj+zQo03lTGAUEAOGdzYI+/atCIXolNLY1urSZQDJ+6n\ny1HTJDrfndO15NjFSObrUHHlH7SRs9FTfj9S14QIKiQEdhsR60vcanlkicNe\nOJQM\r\n=C4ZQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEh0eHrYus7CBiVsBVNQcAysT6RX2/0n1mLB8/vmEi6gAiEAmn30DlSEq669X4tmbTcea4RFfPsj3R9oAtNoq7DjR0w="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5709981_1628068926149_0.08142087298343359"},"_hasShrinkwrap":false},"5.1.5719574":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5719574","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5719574","_nodeVersion":"12.22.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-lh0cFfK5WrRK8Ui/OR720L0RIfa6rwTu/GZj0sgTiGHLQCKkFitwMMNumNB/BAjGeNc8TscIm7Tw8cftyhzb+g==","shasum":"6aea54bd9a38a96a81b1e9bec887287fb2657e19","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5719574.tgz","fileCount":250,"unpackedSize":3306407,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhC9MMCRA9TVsSAnZWagAAQcQQAIk1O4fcrKZBbhFpLnYW\nPzQyEOLbOmbKXYXKpUxzBGyDQ/5wsRwkqX+vLla2ZHykmyNpBc8nuL1ghENN\nvG5ji/gex4k8GmccYS3GDu3rjsfjdLTLUmfexOSmAJSVSJS+oppEf/w786vI\n68oGWnmy86I4NQ66wGOgV3MIHd1kurMQbzS77/YxL9WJPbzSKit/DzA6j1+E\nuNWoZlON0l8R3lz1JhHWXB4yK7huFs1wYcs3fXJzLp58T9RFAjCeg5eapAj/\nRjEKL5yV5BMDbqiZ63R+05tYvrImDsfT1NPnn91b4SaypIvEUTmCP5rrnbqh\nuhBTQUGvzIMLvHnE62tjCT8xOWPtTo01v1vTmtbxXqIEIpniyHMNQIxC7vbx\nroJI37Q8LZPi3mVrMNve+D1W3of3tr5fML6QvqYIREZattusWlrmMTd+/8Ic\n/6xhwaWrqiWvAlb4UgGl0G+/WrX/1rJK2srVie++CjMAAoBtFJ/qHa3raE52\nckrCGOJgC8n5Gcq7K1E8FH/WLg6sbzcSvn4YrE3aIK6GSjAhIbniGdO1mSqg\nqiinBS0Qz+NSkDPIVC9AgrlGAkaUqcoA6EFU5DrIPXg1VtlHDKDgAgrglsYN\n04AKhz/80k3y3JsuUqwBQeffRVWMKHOBZzI1yBbNRiO+o5vf0rL4gL4FQIus\nl8yD\r\n=Mc1J\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGzKNWKJFIt5rNFVlE2Y5eOYzXooDCCFzqcdVZyLfF7iAiEAkZGZvRZ8lEvxPutD7BR3reF6+OuWQlnNPw2KKMQ0GDM="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5719574_1628164875835_0.6588243483555396"},"_hasShrinkwrap":false},"5.1.5721326":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5721326","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5721326","_nodeVersion":"12.22.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-PcT6WMBTbvxuBjDZr6nN2Muys13mAH/bEGpGAIv2O1CMS9/V5g24jzEoq5fSZa00An8m4XJr6tNgG1o/Q7OEpQ==","shasum":"1148e426e772269171dca3cafba81cae6bfab62f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5721326.tgz","fileCount":250,"unpackedSize":3315495,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDAADCRA9TVsSAnZWagAA1eQP/0nwqqHIBR93ZE2W2gYF\nIBhIWuDs8cnXz6QBrxNP/QyP06VSmLNOu8sOmRUItVg6n2MwJ1a5/3xDABZZ\nTHEMkL3uVKPvsWHwgvXyin4/5a6jl0LIuy3ztARtvpzaDUVobdF7Y42X6QNY\njXc1Pau8UFkFWtuidnJLJ0/9kc/INJaAjbBmzCVMkdd1p5JcmrjcFqdVJ61v\n+dFfaOPkFFRt02FEJJev1uJGkVuqXKsVTierkDt0M3/znGBZhgy8P2wzHc4m\n7sEdSbbKfuPG+micFNLonC7EzLrpxIQPLQ+R4Jfl2TG1CV2oGGjvLtS4lU0V\n+zKOg/fvvuW/rcGqlJcuTzh53o9ww+rDOHpNKABaItgC8EPa5Nw/qBFINLsW\nmCnA4F1C7+XpLUFZF4KJspq7aq7Hh2XNNOBkjjNFIXSyqde3b5HCgTilq2Lk\nNiBz3sinXfv+ObvQ/BkTQl6VOpPKwW18SPUPVSD+EQRQT7XXI0y9tu/rPQaV\nWLw58jevc7xVew538mttPurV1fO+6DbfSvbfTiPdrxTkwCCwYgzhixT2RtRW\n3ItN4uSll1zRFftS9eYax+a7Hcv/FBv7eypbkWZMn2uQG1xEHOxKdmJ7Z6qD\nxyCoH0b84uqwrfaofa1uVXJLjuPiKPafaehgKvL65g6siravGIRS/hdyJQ64\nD4G+\r\n=EaHX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDNCJBAFmdstpX6yNxFQwdPf360w5ogenptGJTG7FCtEgIgCaGT9k2N4/ojnRXFEpSWFF4dZMl4GyTJuocpGnAOZo8="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5721326_1628176386895_0.7399064045575185"},"_hasShrinkwrap":false},"5.1.5721635":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5721635","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5721635","_nodeVersion":"12.22.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-EWTn9r+NBpe5dm55rGvbGI6CeRTIMWOOUHnAmBSZnivyRFL0k+XSdJC/EiAPXH2eOxvfm3hY+qu4XRludLunew==","shasum":"33b228730035e7a295103527a94eab8eba5a507c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5721635.tgz","fileCount":250,"unpackedSize":3310317,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDAvpCRA9TVsSAnZWagAAjbIP/R0uEvhfodQd2oTpoxUh\n49v22j89NVNd9OGnUmFGldUOI0C0XuXlgVSSBrzqbetK2KRbHvgYoYmWLR71\nMEU8cGLiOR9YjQYE0XYl+nofNJ+89j9PXHrq+iP1e6/q6NhOXTJvBmSeNAwa\nrsi9BGyJQk97uJhXQ7gw9jzqcZR6IQC369T5No+2BG1SgA4i4QvjQX1X2C1s\n2OIUU0klyYYDRpUJ4RUCBN/ChSfHsCdjsWv3YxRwHefMTyyE2Gs4euMaWN+W\naRKE5HvE3ik0d35TsRyyOW6ZXO3EXiRqJnXA7RyYMb1SquMh2wu9P7jZjsND\nBafiKNZUyRCGmTS8PhcIAx6ZZPktOBofUKowpQWbHMcBN+FHgmOG/epRR1Dx\nHZY/M39pacy4dYqVAlc1l1jz0u/evM7xX/q+b4T7W24INwnUDnqB2MsGj6cr\n9kkRMcsF8736Ci6y1Cd6DPaV/v0khjoe4uUk2unBtwZbtVaa1rqgIbdQsg+6\npidzwuwTT7fqFuhs69Xa2MxvuSxftKhteIXItS8XVomKukCYiBWtWmPRccSy\nc9wI2Flxid0EiyVnc1nkZwH5l8LMATA64mGpU6EFZXv+mBL3cHmXE1qrDfbB\nIgCB1YRQoPbbA9BbnhDDOm0iwqO7GKUbFhzh5icX6fN78n2tmCXK05+gUPGF\nbZH2\r\n=Mywy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDVGTbTH5iMtMJ5iv79MA11roLAiffRPV81enzFW/ODhwIhAInL9DAx3h+Uk3aUovC8MBWK7u2saokPZZn8jJNNrDMz"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5721635_1628179432844_0.5825629818941385"},"_hasShrinkwrap":false},"5.1.5740035":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5740035","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5740035","_nodeVersion":"12.22.4","_npmVersion":"6.14.14","dist":{"integrity":"sha512-wjtpW2AWdKHeVtu58Amy1BrRGMiCJfCpO/UPm7r8i0Fhrgnr28pEEgZhmA/KpXn6ZaewoRCvyiAZEPZSeFvCLw==","shasum":"2a662cab6a5d279d8e97e84c1011a9790a6b5e33","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5740035.tgz","fileCount":250,"unpackedSize":3308244,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEmXSCRA9TVsSAnZWagAA+ZYP/jvMktc7oW+DCPaT0aEZ\nmX1shGbNJebyY2fZaGeMo7hHYSANS+wTjzx6BLPOFXs7rYsoB6HIB3KHFf1q\nqPGrNaqfxgDc9UvsJ4Fl9q/7xn6iYCIUA5vMmNAm/zyvEy6pw5fJhPicKxkz\nmjzPYQn1ESjcoXrGwKuN1EzUvE1KKwfg3s5zNqPzVBAssbrjJcKChxZUZGGz\nGn9kq5LLjysvjcAdKQ+TJkaAuvaSAW0ivoRa7PLLa0ANVuic9R9qYnGholb5\nkUxgZdXa4pm9U/kBoAAK4qNA2G+euoz4iWp3CaQBOLaIpnw7VGMvO2+40LlS\n2gxum0d4uqC3q7SicXIwSQyeYZePBQuhDYiYQRPW4PT8g7M3JDydotmjFBdG\nRsDQfCkot5U3VkGWffGcnmrILFD6Q3hFyO5Lf/6+9skOjrHhTMMJJVDcelFV\nlDpiLXwDwjGsifluPS40RfZS3cAa7r2ZDPx7UkA0ZrnDIcZ1zQqOjfvUVhOw\n4NTE3VmxwdmhLkK0b5g40fwuWk8MYre7VpTQLvip/6jptAMZdjhSjdgrnUxA\n+3xCYBAW5jrj7yZEBSxQirEeUUlPNDbJ1G08j/l/5KtYlAp6BSig+OqyA6Yv\n7DrGLRaOjYKDliBUUqmGsd5BYhqLblxOj8c3YOWDs7JAQkyNlzGG5e2SxBHI\nKfAD\r\n=JKmM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDNyI/JSgt5ciKUTupjk9sFAJ3lk3BIDHTlXG63j0U/WwIhAJukU2BeKr3fu+Kg1lUlQ5hRXQ4NH5aGWkLXlaSITSAa"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5740035_1628595666131_0.013547386189655342"},"_hasShrinkwrap":false},"5.1.5765192":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5765192","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5765192","_nodeVersion":"12.22.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-8a/FPIPc0j4luVYQLhGlz2mNLtUAwdDtWg7OyKiTVdx2v8hdNvN00VFiEbgVAdZl61pTkc18Y4F6hjKPxn5ung==","shasum":"859a5bca46882f4ecf58229eec3641940544559d","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5765192.tgz","fileCount":244,"unpackedSize":3279169,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhFrGwCRA9TVsSAnZWagAAiXMP/jlE+LF5r9qva/6swTca\nFH0Fd2HPZpy7mt+HA9s7jGwYfS4jlHn0SwwUzkeXjyVRSjYupFG5hCL/s7KW\nasqej9Ijhfhh+inc8sW7IOMe+MwiMuNJPCa5oKvOK+FQETf6KYeneGRrhDx6\npEtDoW7T3XQ1NQvttmzurbyBFEaqoXeF2uEqu3Ze7AeyDwNjQe+LXzsVZyHP\nTQBNWXbEyw4qOnflE8YXvNQ8lt6QYOs4Fw2sQjtXZKCo/59kv0EvEm6tzUP/\n9z7N1yGTOQ80Cl4arQwQsJgqB83331eJ4DJEPAL0LmvUzafKtJNkKCW0XI8K\nImKJWYXZ/rJYUVjcqJGvGlutylQJioP2wD4TlcUdbOAMnRdA8OdiqkwSzeeI\nfVJs6spTsKtAojnDVZrMac+syECjsLXW8+uYwQzRWEf5tjRECRoinGfy1L2/\n2N28Bp1W7M9d3RO9RLRDChfT0XmPsnZqhfMXTYduE7sfucIpiwGLPNK/nP2a\ndLzyyVTubXUvclpXitJ799F0AG/YSINsnBDCFVGwZF2rbi1rLy8lFI3U5eZk\nfQqV/6j2MamAxmWj7ak2Xe+EWHs94810+sd2ufcWLd+38l6xyf27TZQ8poAN\ntwPQdFlgUCAjqaiNXa6PautbsYTqgpRKhMQOLV+n8P4bC/05rkrCFdBH9+Ye\nJKTr\r\n=92jI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCKr/me3HDyxPUPzVDnryQht4b6vcMYKPuiIkQiKGe7fgIhAMVPCBgRYGdO8f6JoTkM8+/LmG2l1LwWWyW+lS9FJeVK"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5765192_1628877232405_0.732565595333101"},"_hasShrinkwrap":false},"5.1.5778872":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5778872","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5778872","_nodeVersion":"12.22.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-vfEeEou/hyron1GbeHO0Zrh2zdekjHnG4G2uvd8VH6aksrBU70bSydXe4QgkAw3D3NO4Cmp9Faezzh0S9SGbTA==","shasum":"16684fb44f755708fd594f068bda65cb6ec28f94","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5778872.tgz","fileCount":250,"unpackedSize":3305763,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhG9j3CRA9TVsSAnZWagAA0GoQAJNW6BdoadPPXURyayXq\np+ndnxqY7trUrNIQzH/u/yw0W/QpN22jb1WQy5qh3cOqeTVDJhb5UlrRzh/p\nc47X1YdNdDad7/ZwHD6rneuVDeQUFaKx3RtgDRnHgHbOqgJ+y66HZXmbGUyD\nFIIY1i7fLh3evPotfQdLeS6YhnpG3zwLlgo9Zuvxhioq6jd5VeexK1rj83zh\nd4qNai5304l8IB1UY/5OE21D8fE4yl4l+yFZD1du20oTEIGeyueKZmJEYxQB\nWxQAkgHlfkq94lAde31cV8Gn2R2AcCz65eBHMdNcGdAG6yEH72QqzCJIjVbJ\nb/Hk4DNOfliwAMXeWexHfMnBYhrME9zU8xm85LDEeqZIOxlEmNr8Rn6Mz8U/\n8mTUxwfXt8ef9ZFBbKJjZOoxNIYhNLjLdH//f3BkKW4RehC7NQ90jVfxDTLi\nSHOUPUL585DvHm7BiQYW4/qauQRyX2gmtb8mQ5MPMcgS/OlDvlpznbU9kfQm\nNnEUv/SZDquq9X7vRXduEY6HdsaOZjMcemKyOo38q4P5NJoSuMOioNhWTtRz\nCx6mN6injJgb0ezx7wAMd6n5aINlVai4BpfFjJ65y/Fp+BuDzggAeEVycy8c\n5hE+R5GMt4JgmHv7okOjKdJXXN78BMjYfk2utRjsk8YIzxq2DTxxqBmfy5yC\nROoh\r\n=ePYA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICKS2j0OckuGGYO6pBlteg1rZvQ44lEuUkuoknoxgmOqAiEAioSI0zd2MO5mNTGQG9avxaYyAv571GcKir6DDTU2VQI="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5778872_1629214967639_0.6841279106810285"},"_hasShrinkwrap":false},"5.1.5779009":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5779009","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5779009","_nodeVersion":"12.22.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-qLBZKoW7sOY4DsJOwt1k/JXHayEXhAqn7kF+dhOdEUFddHHRJhr9vSLSY+VfGuocP2T3H9LWNgcl5a24+x7ZVw==","shasum":"46190338501001e1c2179f30ad1c5937908c6d48","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5779009.tgz","fileCount":250,"unpackedSize":3310828,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhG94mCRA9TVsSAnZWagAA6TMP/iM1ZyrML/ilUG4+bNcq\njo+ZG9nHWQtH8Tf3d5CiA5aZZOZ61QB7J01BeWzBTSVoG7xeEdKc1WnfsBVa\nZMtnT1u0qEPYfe7ydB9sqD7XsYok9advg/ORvOlgStcNgNy6pOCv9bi2wxWn\n4dSnFChTJPYCSfas2JfBn8LpEsO3ilZU1pDLOnrb1YUZxOSqDCz4js4Td5xq\nWn9wfgtIyyvI189hk7IegzXsEoZJuq4GUgehj+K/rCU9D7iZX9ieR1XdKRDF\nb71aVNAp68+Tv5W71bienb5Lxfqeofo3cmMDcNn8gmKwmrfIlv4fpGnI31yH\nVhmhubdFKGjl8q6dPqnv/5vWb1YHKWctG6yROrPBJZbd7Rp1UsfDBjHIy4dy\nvolwifQqseQXgVPfhbfrYfjicG8I5cTQCw0pgSdI4b1L0KN2UzT1tRzCZehR\nSBzoEFzZkDaFWIHCn8Wdc1ZjrQDMzV1RwOkUZ0oJ72Sw8hPc7bqjGtKyQNRA\ntsOLQ8DdzWls+K0cPDsUG4KsmS2oqxe4WLGkx5PX/ln5PFCO4hRlGR0O51Z4\nGkA7PNazq1j/BBrKdb4N73gcC6gPN+zL7ln1qscylzAiktDbA5LsMUrIfGbR\nOvNtO7AZeJ5EK2smoNym39vMKm+jwmU3q9n78aBQNb7sHWbOduT0kNKyhPhW\nVuPz\r\n=DvtO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCgI3ORMhqTIbcFxDHxMnCs8DYIdUu/XjS9ZFJ+af1q5AIgHry1ImmbzoUJObfPoKdeLtNooL7/83gl8j2pjDQ1xeM="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5779009_1629216293727_0.4315701581534057"},"_hasShrinkwrap":false},"5.1.5779035":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5779035","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5779035","_nodeVersion":"12.22.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-gaTNjDWYEGUES7+5uYe60l+C6fkRb+t02QLox2dM+T+LJTioGPjcJmSqQMwyd+xvP8hS/0ifF68BJz8EPgk6rw==","shasum":"6cb42feba8a128e28bdb2bf3f16987a51775d54b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5779035.tgz","fileCount":250,"unpackedSize":3312025,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhG95bCRA9TVsSAnZWagAA4eAP/iYsRQhR1ubxFC3Or/5Q\nZ/Ofij4TK7x7Stc9wd1Iz5E2w/C02CwMIzi3zING4u9s2wnBWxsLkwGct+uG\nBjOUV/AxZMFLTPa5IluK6onySV1EIAj8BLCJqzjk2RIalsWIu9QFcFAsYtDi\nXfG+nNJP9TvXZVQyuFzgRQx476jNbW16646x2h7L+LXIPM3F+hd5g50vaOoR\n878vjwyLTA5sCTLHi92pYMyoa4AFQvKaXxyZeNjHycVkZZoTev/Z2HIiK7Qk\niPdGSGtXgN2oAbayvRwQjNloFmx5/I3f2xkuXayHcL+5qGaOSBORRfNyY6KA\ncC20LT6x28Rlix7IZg0ZL0chWXzEaoRDtj3d/4+o7PY1S/YanMTJ0vQTY/f7\na65xJU8Hisw8wAoyBPsJrELP/TGLdOBW9NogqMBIXIeuTutCZjwH64UvBYaX\nEoEzNrwnB23d+D/CNF/vr4+bhkq3w+FbqW8zAELL6qbRh3638EZsDX2kDfiv\nz+gIFJDoBB4ePc0xOglhOjJSZPb0liqESfDbKwK47swlJFIx+9OuNZWA63Fl\ndw0JHNU790gk+MS8Nw9BDNaFsR3+nIEUV6iCJC+5biwSeyO3KB+bB4lAGPRS\nlKppUf2++x+3eQlVAo7LJnZbcW1vZ8WQrpJNp9hEjbh0ni6blioXzwAYQOn/\nZQRi\r\n=FPQ/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA7MrYLuDBz56uzpbIjSglat24GLi5I00iMjSaM7sYC5AiEAqNqYFsb03d1hqkDAQ52IQq7tnV6hFV8WQebtJWOHqAk="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5779035_1629216347236_0.8452568250071624"},"_hasShrinkwrap":false},"5.1.5780952":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5780952","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5780952","_nodeVersion":"12.22.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-ipCcUYkUdaRIBx7/gT2Tg443G6vvSl+QpAuAi6AgzmHtPYOvM8/u1fBDjMhjwINiPZ9lD5s7hqPl3hl/7KIr5g==","shasum":"c25edfb5b7b279f185fe01670a907a0687c556f6","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5780952.tgz","fileCount":250,"unpackedSize":3312025,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhHB+1CRA9TVsSAnZWagAAeYoP/0Zyt72V/vu1GwaVOkJV\nci6oXWtYM96Z22W0nBVt0aB1OJjxFXbfLzuhVDxbCPZE1nyXdEILJiUgL1g4\nhHTbpT9b8FxZb+tCR4uBZOl7xxofqZ9Syi7HTbdWju9+Gxxdg7wgtaiRsBuy\n79n1zvzLryVMQXH5Q1XamFux52NOewPlqj4g/bvXMiMVTF/Y7Gis3K0O+OW4\n6Hc5Ce7jdLXi0HyeT+xf24TZMLWw1G3+iikRH0/+tLwbpE/PrrE/SaEtBMwJ\nJrP5AREbyCKDuRab0mgPq6ZBWZKbE4KNkI9QZ0DYtNtfm9Rq72n1OvM5zfCl\nDm6bNU8kIJtqqGLI47/21IRNJX6qRV/jUOTuJXuhoytexUKuNiWvLhOqjexZ\n3hk1NjgxCzO28D1IVMrFxXF7axnPMvhh3VnKqRKfSb7KPhrjLogjgvmkfM9Q\nyCmDwOBE6JSmCfWV+FP52vprn1j4HZr3Eg7AUZIEgSJG9sj4JZnpK/NOogc+\nHyxrX48kE+NKeKmgwsDXdLCcS+TLUYlZb5imbL9D2lErebjptk5A8QmMmhvb\naejQuDueL8QN7DV/Ydr0wpsVmYMN/LZRhXZh62mFj8Sa3f9ly3baQYHcOSUt\nV8hVeMdeHS067F3vGOM7zDIQEi1ZrVheSylWa9+XdFSC5jeu7cPjykvy58qK\nHQTB\r\n=cJx/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDGbyqmXQOJ8tpezBVQ6mA7dS93AS65h8UoBOyT6lTfPgIhALJWayUiqj89yxfb+/cyTTAwgdsW3zlud6UQx1zKx3O6"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5780952_1629233077174_0.2878413738591339"},"_hasShrinkwrap":false},"5.1.5813039":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5813039","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5813039","_nodeVersion":"12.22.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-eJLs5UdeCD+DIMCwG3bN14r/UQRfcZj6fsfYOOkhnUgp9fv8cl+XEzhYROC5an1Wny4o+7zCWWwbklGvvsK4rg==","shasum":"81a6432b75a2e7fda36672b3394d292c89e289ec","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5813039.tgz","fileCount":250,"unpackedSize":3310999,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJQMyCRA9TVsSAnZWagAABTQP/jYdcGlIGNQXcHZwM0hn\n3uiViGNDZYWwyhrbMboGAgViGum/ODTNrLVsKLw/HjFZpkWb8bloVNVqhiCZ\nXBvWWn7BIfIA3ksPaa165pdzzM2Z75aqh4Y5tC2ytsb+Gu2c/rNlPCKL3zE/\nA0F9X+zB5XfbTizz4WWXOVNehH6yuvYBGHoIb5xtgU2a1Lum2O5so5xqqeot\ni4Oez66PmQMbFcj4RdMVFS/CVZ6odubMkMJXyCz6Hp7dyzjQeeR5DRtf2erd\n7PRFN7zk298SaUM7rFUTJAkM9tfmEOQeUOC9kapWkSIPbDs3/3XuV0SF6AYd\nyFCKMjiPLk6zWzuAGV2uFbLQUJty6PtVLmyc+oyKD+os2/lHt9Y4WJYBZQMq\nSi+c0bcX9IQfpii+Ar4C5jUSvrk1H7BfAaYuNzseZhqGvPrAYMx1fvo73d2H\nwmj331wb12vO6HdZa3DnBgfBBO0perb1vcIrGQya0XeD3JVFQFLoFwcdZcfV\nhFs8P6Fp7NTa2OFIybTqLgAO/Nc3PXHKxK/LPzyWnfJAcLOxLskJ616rcvCL\nS7TFsmRSSbiP7g9YvmoZfwSAqw/2VkFOcDRtLhZkmwH60HEZsSPl26iOgQ9e\nN/PYcIVBavih7wm6zOHKp4paaspAUkUrdSiy6m0sSVnVFJeXJ61Ip44hls+d\naciS\r\n=4K2I\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHHWS9OivLeGNvHt4R4I1TQQ0Y68OcXwLGWJEzj+p93EAiEAt0T6APhdpP+DotRCe4W9Yhhz6S4kBGnIoq/1Cd+wRhI="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5813039_1629815602643_0.4840713867834212"},"_hasShrinkwrap":false},"5.1.5813271":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5813271","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5813271","_nodeVersion":"12.22.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-J1JSVbNdnCYTU7pjq3ghM+MkqnfLg3iABMkdVi/RbBNr3Lmh9/XEp1TAyLMAwQy8e1M6AaMdTq8N/YCugsFveA==","shasum":"988f346e0e12da04ad30aba68a0242cefbeea93a","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5813271.tgz","fileCount":250,"unpackedSize":3312196,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJQTnCRA9TVsSAnZWagAAiJUP/1S18JJBobzDrU4BcCoP\n4VTCwzc/0mM3B7enazKeZFknwpN3pNADKK6a8ORJuFLST4obngSLKDX5z7si\nL+IbcXIcUQqyu037W6mnu4fikfx5TS7XIjDK5F+XhXztSd40V8Sx3xojtAbL\n+I38WXSJYg6DTIC47gVuNfL9dBlJuHqJi5YTNswmfGwKZhBps5YSnPHxuA14\nrkPA759SD8u096pDdndKrqdwmUS7lkHY10lc1A+LW4e4qoyX/We7Kx5ilSQi\n9sCFm3YQRBF9k6mTeLzFEICL+FTj+c4UGtEVjWcYaDFer5dFKllgRCr+qDH1\nXWbKlk/DGh6JZqqnpqOtyQlNA5V2kiiaJf3ANMLTczj9ZwoybO+BZW7FEga5\nGgMsQEC59m3o81qarEe6o4zDSU0vvlbvuwBU2l5sMZry/RwaWiRanCHQZtM6\nkqi87z109rTSle65yqlnZiQnxDtrF2YxW4uaLobhPP3Aw5Qfw79YhDgYDneM\neB5BN3WbKRQZ/1X+1zZxtssrgfF2Kuai0F+BcD28Er9PSAWYLAWEKA4OqTNy\n5AnbUPYmW22tlUt69xgTx4NWCVf8cP9KCqzQcBDnomPRmJ+qnH206ttN3GeZ\nxkjCqoa6DwRa7gDUWIaeOqTYtOgGKaPHCyVFcHv8VQ8eIB+vdzijuPFA756f\nq2HJ\r\n=/bwu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGjM9iNrG2HW0jv1Y4V092ATPKUwr1rKPaoZIK1X3EAPAiEAl3V35HAqRB+MbXFRqnlB2GNgCsGUxr8IoikgfIOFGNI="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5813271_1629816039226_0.3285007735900096"},"_hasShrinkwrap":false},"5.1.5821051":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5821051","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5821051","_nodeVersion":"12.22.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-aZFGzg+bFNiqDP1hlOojNLFefXeKKRUru+e7WAPbD6lpM9oVa9fBmW+5eaVvorf0ufIrUQAwFLTzEMLgUNfsjA==","shasum":"323d2acb5bdd1baeb694e5b61774f3215d929e2d","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5821051.tgz","fileCount":244,"unpackedSize":3279169,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJnPOCRA9TVsSAnZWagAAu/EP/2N3xgEK3gQfodHpZBvQ\nKne4SUSJjCyV9hP7pyr9AuijFZaDvjii0YoI9cgLBU0/5ySTK6YlG/5VArD5\ndEh4cxy57PNbzMmsbn5N1Qj2JQTdtFOEZhX9xaClmzqtaOgaj+PglHCIaIT0\nAdCgmSrRWIB1BfJbsYBFXEzxr+IU3wWAS4yYPLMN+jr48KKepj1jLATBIXd1\ngbtCa0IDLGHi/BQesMPxdakEE60Dwnw0s0uOKUVQGIq1dWGKMnJ4SRCwPIvF\nyJMql09wZdLPTteLyXbLN283f1ns/qB2WGz6Gb0Fe8Bz10hX3B7cgBJLEgLb\nHggos55q4iLKlFy/t/pJnvmrlVkrik777NYq7zQ9kLQP5hyOlJUZi7jxFfEE\nIjZYLsOSszRpLIt7YNLlUesSjPgLEg9jPWR0yMYKHdDcnUw9SrMAw9zPgKaV\njwSOSS1xTN/jDtbOn9Q03hSVSLzZHhB1KvD3cF96SsBhnQIlHvZzOPkgOzIF\n4xTQkMNclCWjVboFvS+P+7SdumcT3Lx+vixxpueBI7bpMXuvVEXm12nNCO/x\nuunvDcwEURUysRdcmTT5jA5iYy7jk1inMpo0tTGKi1fOrE5YxuSvHYwZhZWd\nnkNrVEmWjKagIoTRoFdkoVjFYXKq5xwc1xvJyWXbv8pD507xMoYdxJns0DSS\nqTMc\r\n=a0a2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDqPC369HC9mOrpoQdm+71HBHuF9GKNxr3Ch5ZMcK8bNgIhAJgAb9CO9xZ4w9qdjPFbpbdeCZuMptqFzGtCDPc8aol3"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5821051_1629909966035_0.9961547852991017"},"_hasShrinkwrap":false},"5.1.5875795":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5875795","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5875795","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-9cz8Eku9iXls+d90BzKVQszu+07GyNfglWmWL8D6p3/L96W+T/VWvhZQE2EDCNDKaEX8H//0ivBJeVdcnw/xHg==","shasum":"aa6c12841ccad9d5ebf7db0cbe8650acdd0cac1b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5875795.tgz","fileCount":250,"unpackedSize":3312196,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhNyrKCRA9TVsSAnZWagAAU1kP/j/JH2bdxDeaTxqDhCXf\nucPEP3VzvrwHhJWzr6zLwBdQZorZClogDsAEl3X7Q6H0gIJTskC09TVSUmUT\nBZXYUpweEPSO48CSrEG1VxnFNwLeE30FY+g5QDYw+J2AL++eYDiBOvSPScac\n+Xfq80oq6jh41sC2b+70SCBt3qANK9eBLrYOxGtE0cg7+G0Ey7zYrZbgQmtr\nIM0B4e40968erDgtH3IPFgZVri8379yhnOavzj18y88NYVpkEWfqSfUXJ+J7\npBRNghpLlnRPJkms/1HGta5P2xiW5Ul2FyFdHfE6VWfjbbgbSHj6xZdB4eDz\n5NlTr5/8Fmrebs2/urxX9+L8fMUVB3zKxo3+PbFvDnIfeWY2Y0h/ivm2bcsn\nDTD6+Lb8zBqCVatscxGj4jjSDnFA/f/4vpQHqdQHPx6Rv1yLxzZ7BaQsNSJA\n4DMcwcpAABSZbqo2fS6+tjGDE/TAWN9a8WtpHRm2BHvMpX9IP+030fShpDN+\nPfPoL+OSCE/2oG6f+cAvDacsx+sPI63Berz9S4RJkCnNuo8MSUXDyZRx+rXn\n6ynfkSuvYULihGJhJSjnKeL8aGe5zLKX3Qste16uYWQT3xBvcLnbGgNT55LY\nRswz0HsxTO3DtHEhzaIQQZjOJKoHAd3kbEfgU6tnsNR/6EE31rDa0GasWN1w\nywLx\r\n=jc4P\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCPWM+7HC16HHgE3C5XrbcqByxaFJcUtidrMpFyFEbebgIhAMuGviBAQV9bjBD8aT7FcMTCUlxpRhfMCQ8jP6g7MSRe"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5875795_1631005386363_0.09842004297717843"},"_hasShrinkwrap":false},"5.1.5881112":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5881112","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^4.0.1","rxjs":">=6.6.3","socket.io-client":"^4.1.3","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5881112","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-l0qUdtRgSAgQA78rEa4R7J0Y/bhpxM/g/lEZjnz9ampZib4bI4Hv+Af7oWwmHuHHThvAY3OQq6G/FA6AeMTevQ==","shasum":"d0a0bca880613c82e2abf0c587800475f076ba1f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5881112.tgz","fileCount":244,"unpackedSize":3277888,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhN61eCRA9TVsSAnZWagAAnbYP/3Yu0xiYNCo5g6FOaZ1R\njiPR4L1dNpvjtR2ONLaHkysJYlwXFvlcJ9hNcQwxxriZHFmIU47WFpUsRWNg\nMOdUdK7QwBCFOmjb/tFgIMVGFxCHtZTZY018shMS/Jt4QDdoza6EFHCI3YCc\nepShhdp3sWFQFUTBxKosQ+xwSzrvemhbGAuQ3wIRZ2ne2MwFISknz7bE2nEe\nX8nAF4RoEhvr97Xu9J3EXtzZ5Kvf10q8lkDaSMzd5/evFCdCS0fVPE48GW2I\nDYSTWOD5wpf5MHBVvwztK77oQxQ8OetjREb3ZDemdeZbBix+BQaI3PyXfFKq\nTKJw7ldzMejdd3TPlB9/rjxzcl7u0do4zyiF62qTx4152TolXMm3gdXPItdt\nh7nNmhVG7VeeCjqXSmeQ26+54M5pLU/sDw7ci35zCLP11t63VG2OCZS7JJxd\nYRPG3CMysaMVumBrTFLG5e1Bco4t6XfXW09vf3kZNfYdge5UqwDBY2Zns5sv\n3sp7A+nNDnXeeS68RA/Nd1EiqjY32EaRWgkGuaJgXBRee8nZXhvDPI8zzvJB\nnS6eQGBirzdyXr8Xt1LEvq0WuyWw+X10PKrtkCmEhGPlzRR8N5O7pPtgsdX1\nl7b1quVKIBDWdqY7mXPh7KXQs8LPyu4yMJhAGAIWa5DsgWn/e4d1E18kVDxB\nwKBT\r\n=0eKj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDmudWvZTp6qoJNi8aKQe4IxFzPDELafr2dQpuDQoNU7wIgNLv6WcwsIGnSwmGR/xX8wU1XiKtKpR3HPZHoxtx3Kpw="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5881112_1631038813845_0.807267022148874"},"_hasShrinkwrap":false},"5.1.5910440":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5910440","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5910440","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-u3EJ4fiYVcl+yHuzVa+P3pn7AukihP3ZPSAAK0Ed/cVviHTcHZ2186qicii6RA6EMlf9PCvf8r0YN1cZBlnq2g==","shasum":"af172717c624b7e7d8b3eb96669290ac18fb875d","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5910440.tgz","fileCount":250,"unpackedSize":3330103,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhP4jVCRA9TVsSAnZWagAAjNgQAJGoKrvUZTNzQdm8refX\nZEOrKWnRQP+0BAU9yKETqQQcyhH5FwewQcmsd8w6UTrLlgTjb6GnalUB/B6M\ngfxMxHZjeRgMoE6Py54lLEnJXbqN5bjSndm8r7wqpsrstoiSI6yqlns5iDXe\n97hTiyE+zMuI4nFtcAtQV9oLEIKPpULZFF83hZi5HbKpJwlL5xC6NOJqcmQw\nXDlLaSEZ9wOW7rO9okXAOX3K2jkQHidv78uJtY5C9z8HXObeaNI6eminE0FH\nfnag5R0i0l5sZbyDz7seL8f6VheTvzJPnQdcqqFTS+gd9Z07othyLI831vJr\nXWD5qh8JJVlrYb6R8V2r6+Y78hnTR86SeJqS1YbINBgscX9RsyWqGSlgCqxT\naL3ltV1eXCRTb/gS5AHsRQ0aSBh8wynxrm4tQ8RXA2rvQmJJ8PbTna2mV1gL\nZqhZRy8VGnmfUoQcLK5KBXvN6ibou0nqMUYlGFJuFVNIn4cHZpE1RI1onoqw\nHIhfjoqflM5/ROVADkOMrlFmKa/pBvDlMaGP1JxJG08IP4kyDMFCXwBfgols\ni6aS+yjNKX3cQk602wNW470jBJ9qXPKlEq56bMl0zqwy+jPUqZxwn7YktTD/\nXvXa5MjoOxln3OuzfxMzUh1Xd07DGvAvCwOjrdCE/4mDX6gI4AWAVvPGtOx7\nOAyv\r\n=zaVD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDXsYOjk3oZNH8cCFMWCpqV3WuWBeO66iLPUIeO+VOOXQIgTbeVTWAX0KdkMiIKATMLZhV7FCjmL1HBDrF2WzjkhOM="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5910440_1631553749056_0.03216264764192789"},"_hasShrinkwrap":false},"5.1.5912653":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5912653","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5912653","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-NubQ0lV4ybk+KJ7kaSIlWN5RGomlO/Xmlx6lyIKMtsklGClzzEmZyy4TQ4BizpOz7K/Xl62ydSGVcmAONaImhA==","shasum":"17134167325c07c1b8451be9d79408c74ba3bba4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5912653.tgz","fileCount":250,"unpackedSize":3330103,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhQF2OCRA9TVsSAnZWagAAXGQQAIfLAY1CUWDZZfs4hXWs\nuZs5RgtzKttA/4qQlErD72NUSAuZ7Bhp++LoDP6/wVjvLptFsuU6WVDiYFCg\ncnZd1dJzVZxk5tvU3DSC4uLxQT0wZwPXYhjenbnsiu+ez5QgSgSCAcEx5ZI2\nieChEWLshsxtYVoYpo4yGs6jfFBo1owC4OeZIFigjZpqwK10s/Z+zpk1kRMa\nQebUWZ5TBqhYqUwNUz/Sg8tAoz3WNPVaxNQ1p0OkiuvwjXz2Jt00XQDq2NGB\nxv5VrlBIDZ8hhX+lKOoP0s3WQFDwJtCsUYci0oySlE0qeqYxFwz/RjWZhtA6\nKjMk5bfKkKayXFXBiB+JTEHUMKGc0+2vbdAFUrb7uQS/pYR8YwEO9ANTBic4\nPj49VLrZJEmEauklBBrU+Bpdb13Yi2ET34I9dA6YXZlmkht02gO/AqksA0V3\no/caPZC3VbRUGuEnSDBd54WqIxQUCGOt1T15Alu2xsD5pHooW+YZ+j65fwrn\ntRpKCaGaAs5cb2oBD/6J7mbnpspC+AJMMfQtBi2YLgh5GxoV1hQtfIAE3uLQ\nalCNnpnyUINJo/XZuNhPmHZgJjrDBzrJnJP7AhiQa134WHzGQK1Lzn4sAO6f\n1B34UxsndgOsqA85pGVRfeg/obVIfNBEM7IhfiHtLnB4c5IAyMH5+E7UlBRt\n+Uje\r\n=UsMu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDHsbWxBdle0lLtMHQW10I1hHXfgBupyRQLC383Ci9wXwIhAIUQE6ANQ02Htpt1Sd5a/HUmO9vRzU0aJJ03aUrTcuGW"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5912653_1631608206386_0.9969203156466209"},"_hasShrinkwrap":false},"5.1.5926490":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.5926490","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.5926490","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-Ab7kUqHbfe2IWRqyDMFdx/mQxhjzB28D9o0RIiulRx5BWIbJfXQbpFGPJ5lg5PzMcNBlCmHMVcTF4JQZC0cBlg==","shasum":"de930513f48ddccc8ec12f574eadc2a21dbf615c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.5926490.tgz","fileCount":250,"unpackedSize":3330103,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhQx51CRA9TVsSAnZWagAA5SsQAKKAN2EyFXZ7/0qeuYjk\ni46cKMbntXOyIUIEGHeC+UZp/DjghFvsZ1djPVRSyo0w8iHj6MmApZ0/pLMw\n8hYMOI5+Q2d94LU8Ek43KqRiJcSJNmFxFJcglmrmruimIiW86x/R1k4ClBHw\nwaKY62m1o3YLJnTBbrEwJ+fnn08K9wZi26qn+moFfTVWD3tLjvNOflYmJTCu\nRXo/sQIseV0slf3gmduKXX68d1LomLSIfD1HEWT4tDlQiXlFO1TsCA/jq2HE\nONWfzPyzzO1kaLvXt+jcTrsToSUyrCZKE9EcH1QTApDo3qakwlqvRfYgk0+u\n7BxWRXpjmf4zw32D4xFsOdQQzxPmORYNYqVcuMrzKrGBTLcPcpgyOaXXYjlA\nYDj1BBc8PCKr9t/3GAMQl5l0f9CwgWm/kDNkQ9N5FmB+hkGxaKv9t7mK1gQW\nuydtzEfwVOFxI4jgW6F3vvDJXofLsBoTPi0EzogGmCpSLDzVnmnWFCioc39R\nrgTh2NobspjW+QRDCdZnKI8vsgNYgtDe7NTn5PSywD7DBRtjVzelQM7nI4rm\nrnXGw+rslQcRKpMnXX/ru30sMhvBHoEwfruRXri9RQgOm/R4j4lFikxNNTV8\n8dSp/43o/rAE0z8sdE6DRMrGIdFwcFs17r2NrUubpqqtT72S81Ctd26Ms1ha\ntUPM\r\n=0+fA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDCZ4J2nSTq7XoeOwK9otx5E/H3VKJ1txBvGlcWUr1SVAiEAuV17Y1/xFZ5/QtPg5zR1b/HQWEPOUKrA+Vq8aFMFOr8="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.5926490_1631788661741_0.9749725553764941"},"_hasShrinkwrap":false},"5.1.6001567":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6001567","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6001567","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-HE2JrZ2S55zJbyendjnRpDTuqiaiildnZ71ddq1sV1sxO2755LyHm+LSJsqUn/Qk6p+xC3n+v5KCcfvIPH3asw==","shasum":"a746e65dbeb2025f63487d0160ad67c0e28b55c1","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6001567.tgz","fileCount":250,"unpackedSize":3334713,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDQrwsjQR1sQFFcAbWI+vsBj0ee7ydH+MIPtule+uM7CgIgMdv4iNYi/8wN1Z+LqRzHl1pi1r1BlNRkBhwt4HJs7uA="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6001567_1632843950783_0.5359501440115355"},"_hasShrinkwrap":false},"5.1.6028772":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6028772","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6028772","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-incOs8Gwdpb93veoS9MtMqJeCpAeVr0NBTLueUNd9iJi6JNuOtvBxCq1DEdcS2LFH9pX/aLm8+FcWQvADnqIyw==","shasum":"c026d0b04d524c96ebba93cf5799104f4cb4b9a7","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6028772.tgz","fileCount":247,"unpackedSize":3307834,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC2uQahWWRoYgJJU64kVtIgK42Hry5umaD6rTjIGZUXbQIgWMDjBNbSziFs2KC/QnuKLjXoFcUWlfBPzpgZWQ3mILY="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6028772_1633101804247_0.05933131651405055"},"_hasShrinkwrap":false},"5.1.6058802":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6058802","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n// list of all options: ./lib/default_options.json\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    user_agent\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6058802","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-kiM535G0rQ/MkawTXuXw6KKpvTJKdgmpGFzPpW3uNkCBcx/xo9pIwrKzQgxCBfRArZfZdqLHAY9cBFdSuY0zgQ==","shasum":"70d29c1aba12bce3f610b6c050c66fdbabdbc560","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6058802.tgz","fileCount":253,"unpackedSize":3340020,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDiJ3RUeDL2G/8RpATkK3+r2435wa0TCcv8ClUv3j/9lwIhALTc4OlMu3reoDyJfUUqW8rEKT3hf57SFeoE3uBXyjUy"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6058802_1633532070740_0.9033697914907601"},"_hasShrinkwrap":false},"5.1.6089496":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6089496","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6089496","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-BNCn+WchpKccZYdywSN6NSp/crnpVN18fWkOUuyBGszJhhbICpiVF/nk5iBjK5W84MsvkCsU8R86lrst6YaANw==","shasum":"542b65505536eb1a9806242d5138c33f6c9abee6","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6089496.tgz","fileCount":257,"unpackedSize":3339945,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCy1A+uhvKrh4JgH3+rEkQA6xlQ3yw4UwN3c13JMc1rmwIgEjeFklMLJ6TGpabt7TFA7d/5SJLZrwC+joBGW1hnHho="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6089496_1634059742345_0.5300874943417966"},"_hasShrinkwrap":false},"5.1.6089492":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6089492","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.3.21","aws-sdk":"^2.944.0","axios":"^0.21.1","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.2","graphql":"^15.5.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.14","proxy-agent":"^5.0.0","rxjs":">=6.6.3","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    agent_address                           // Geo location and ip\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6089492","_nodeVersion":"12.22.6","_npmVersion":"6.14.15","dist":{"integrity":"sha512-Hg8UI9WXMfy6EVXJYmKgoO9x6bI+3/r448CcuLKOT+Dgmy4kTFYV4i3ArVKJWa2ZCLxOnFXKtBwy2EFai1ncrw==","shasum":"de1a132911086343540e090ff320295866602c05","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6089492.tgz","fileCount":257,"unpackedSize":3340395,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDXyebZd1I8AP5YoFDm5lSbjAp15LQ4k2wnRck2XVmb2AIhAKpU7Tx0Sw8yjWRKZTqP5BfREv9a8ymv69Ipg9XsUctG"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6089492_1634059745857_0.710525274776731"},"_hasShrinkwrap":false},"5.1.6099804":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6099804","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@improbable-eng/grpc-web":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6099804","_nodeVersion":"12.22.7","_npmVersion":"6.14.15","dist":{"integrity":"sha512-1U+vVRfqkqaeWPowrISs//xD0LvSm2Ac349d0Rg4J7VLNEeo8YYb5quqMQwZL4h+U8uhxQYfQVQFtVNKgnFvog==","shasum":"32608fac9c9559051956f9b79f07c0faff68f3b4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6099804.tgz","fileCount":278,"unpackedSize":4650178,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCTLTSnqQStlvQ6/OaHO4k/iZ9PDX//zg8RJFG6Vv0pUwIhALtU86emmm84MadRB+K4ADjGdDcwQePUTSdO30SvM6fj"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6099804_1634202026286_0.4014852501628863"},"_hasShrinkwrap":false},"5.1.6269660":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6269660","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@improbable-eng/grpc-web":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6269660","_nodeVersion":"12.22.7","_npmVersion":"6.14.15","dist":{"integrity":"sha512-CfWDHx9OByNHkExPetmB5mSlAF0bB0pxjGI/l1Z+UTWTA1Fvj6yUIGVxTA5Ftmk4jibCAaNBMKLgFZFqr1lEXQ==","shasum":"d7759bc0cae4672d61f27aaba05ef89e6aa803de","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6269660.tgz","fileCount":278,"unpackedSize":4650366,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhk8kNCRA9TVsSAnZWagAAgLgQAKRrD3YbYeLwL2CZxcmS\nQZzVIcljWbwOGHpnYmlr/oHBoXlULc6vq6BVcR+ffXn528HVRaFOMMHWEk6y\nRBl2E3lvlesW33de4ijHAWmCHEs2MOv0cjHSzMWcGsrFzHJ6jvJ5Au9/a0en\nTs8t9/oJOdbBsSIMTEBcuyxvEiujtx/SH+krvoLNpjT80eITD0HlkVncY9tv\nrhLMYw2aBo3/TlPkJULXQUAdBwdeyGkmE+3ctKXZWWmWhQwEYRoD8D6EQfUe\nyVTRSBnDCVaFwOmh96kbYcynmoszJ1aFAGeKo2o26YQhr6GiY63YaTEPbtrS\nvvbFgmM9F/dMaBXhtI+PuywS0kd3Haagafq/rRftm6Le/7nGXSeb/zePPYzG\nNun6jNfUwHBf3Y+tmJG9CSqJXPyGf4667E1ECbInpQMyESW8131zJzXBuRmI\nV7HguJ4wm8FBJJ9ZFp33lKHPKnlMo6pAh5FeWtZv93cY5VHM/WVg0Ray6Hug\nbAiexQ67UG4kQFlA4GY6JV4FUd66TGoZmhW71ZdM/gKhj2lsiQVB6RxdFqD4\n+Ah0VWnbL49OXA3w1Lg4WZGf4mYCRS+kv9snrWBOo35URW79oMU0o6ol0Fh5\njcplgApLyVwi/xPLsyIDk7Ca1J6j7QR8F401Yghgv9aZIvgGm6EQOnWLK33/\nAAKa\r\n=s3B+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID7Cq7vTKX/GgM6Z41ZQiGu/ydloJUJzYgIci8cpkGDYAiEAslIkljBu0yZPwg5B052AlyT/OMskUlP61XDRbjUMqdg="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6269660_1637075213700_0.7004674233392838"},"_hasShrinkwrap":false},"5.1.6338234":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6338234","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@improbable-eng/grpc-web":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.3.0"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6338234","_nodeVersion":"12.22.7","_npmVersion":"6.14.15","dist":{"integrity":"sha512-qULHK5H6dFmgTKpDy7JBq97+b93MUhKdy28XbXk9YLqeZuDVq9qQhHT0/eosGVPKyityhZTFU+riqm6Hz2oARw==","shasum":"98fbb0bdb97dc2072785164ddffaad6804ee8a66","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6338234.tgz","fileCount":278,"unpackedSize":4656078,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhoNufCRA9TVsSAnZWagAAQSgP/i5zrYSnHszmJu5vkK94\nbdtZLFFf7z06CZVm13w7PoUG5pKwsrHdygcKqMEZ+z9g8svjfex47CxHCVcd\n5SW04U9bCacbyC18khKKA1C1E/aaZ9stF5QUVEKeonrTeKy9TyuzYMxJvl5i\nOT0HTw4fHX842x+1SmaKu6DbTQb+F+C+qnoQnPzBHk9ICJ8zIuDUBaO8z340\nTrZEhJ7w0vehvD+Sxs7Px2HKSsdnM2tnJT0m3luKUSo7DFY+w6xGkAABFGC+\nSu/hrrJIlgBkxSRr7/RY/JNV1OMNQq1zjGWaRlDBbSa0LeTBnK1lqD/yoScx\nsWkzN8JTAx8cu9eo+cFW89wOPuV1xz7mMNXK2YgRAqHmKEudhfT9zkr9zDFY\nrT29wV6QlkOFA563ffRzFeNLcuFXamoVyZjnoqEoYOXIHmYBSbsL+qU743TS\nTx3opy1zsOCxGc/JDkHAo3ZaZvwbKpqkojJIlaTX6qBnI37KpbgjDQFNcDuX\nO/xj5X7YbKaqwSb+SuffeMp70h+PQX6OxDlBIy33eASxz944l3D1GIAF/Dfh\n9iMnj+51ydoWCuh/p74jRNkeeTYr5fcBmazA6QYykiMF/xl+siKGz6Cj9toK\njfOeHti87zaRpfV+1ANTe9Mxt40kMtWJclChdm/wJJKZHAakAIAj7ZApkDcA\nT+3u\r\n=y8T8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDKOK+2hqf2+1hbZKeRPhhN1xmbBILX6j91GGO/DChQBAiBlnsxpIsc5FqM9xUCXd9OlZwI4BopPyjmYBMSUzzTL1Q=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6338234_1637931935126_0.2843192131125476"},"_hasShrinkwrap":false},"6.0.6356455":{"name":"@metrichor/epi2me-api","version":"6.0.6356455","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/index.js","module":"mjs/index.mjs","types":"mjs/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"c690264544fc4186dbf87064a5ea99aa986d4b3d","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6356455","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-uPcyJM+eWPu8S6aiRu8ITyj9kcQqkejcI0u/9RYtScVj3YxCpxDJ9h/mAnllrt6pd5kwGT5hOXKI1NDZUQS97g==","shasum":"df8133cbb4fc68b75af441b8091e533bf3a6662e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6356455.tgz","fileCount":1206,"unpackedSize":3811773,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhphjCCRA9TVsSAnZWagAAE9YP/RpRCk37XPk0VslPTP4j\nDhX0GZCmtgN5tK4fr0E2/GHl71kcLMp1qaLk5enSFc6xPrn/40R+sKD+mVFk\nGdh1mg+dOtAgbqB1uz1I5sqRnhp40cEVqSvxyNW9NFJabuPg0ylQ20RD4VRI\nWvwEJHp8YEOp5w0T50FOQSKT5FX+Ig7sp5wMaEP1OihS9a8m7iIq1qJxaXKf\nve5Q2zGWOMEq0dXVG4loSnOLIqV8pUYQc4VWEGMalpRhRuE/dPmXFcwgzWx3\nghNV21c3pKITRADJ3FA+RndOnMEN7qR6oGs1/WS1yXBA9FCGGfIpOwnVnbym\n+qWUhxmT5VCzaXZgu1kgnKuRwhXNinCSJRhk9l0cnPIjk0bP/osxZPHsseNT\nZaKm28npLWlaWxIlG3Zqk9nwJOE7AEcusHlpK/oq/JjiXCOsCFEQAwBOuS9Z\nGSii0dMF1mKAT3TGz3fiABerHQ7uNwML7B0DnB/Jqj6APtaRvOghs56Fzwx6\nw2+0MSghREOKUZ7JDxBbpAhQxBiK2E+33oEmJ6Rvq+KFvj03PDTgzASlt/Ad\nqoGyoAHnhH8+wOJmVGPr4QRE9DBdnCkkS0Ok+2zYI1RaPMWluKV4550bl6ND\nfI3boOd1JFEDm0rDIGz6Jff3zYiOLmI1SHJADg/DIatYo/hbj4S1tRS+WYB5\nG6mg\r\n=tCMn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEt93jum7E8L0ZUF0YkfnTY4Fp7JNjDI7Ax5XRLJy5toAiA3cEsFfGD8CZIvmIFPHW172KtoRA81HeLkqiIRVgJX6g=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6356455_1638275265972_0.7866941444545974"},"_hasShrinkwrap":false},"6.0.6359806":{"name":"@metrichor/epi2me-api","version":"6.0.6359806","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","sqlite":"^4.0.23","sqlite3":"^5.0.2","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"8ea159477572d95d32630cd303409a2c1a2247eb","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6359806","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-ZWrJcaAd2xNlMvaxEFeHatm6Nv0NrCVHLiug729KUFImRJVqcLVz9/pKP8uVPSQTeIPPbYMMe+7BkD33fXM2Eg==","shasum":"38bfd83083968aa42e8c80265477080d48f58336","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6359806.tgz","fileCount":440,"unpackedSize":965842,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhplbICRA9TVsSAnZWagAAYhQP/iVIHfkmkqteC0Fct9LN\nGoOuvT5xyzTUFUrhznJbh8s4ksn9Puoc9ojABLjTru5z4LXXmvT2GClrm6W7\na5JfLHWLem3m8pFstCROVtVSLqjWHlhNHGyG5nC3TfAbD4KEzDoUYMnV5z51\nTm7xMvujgZLcIsowXnKFrbl89YWqNY5f6OGZEAdjmjh3uYn+GESZuBFMojfi\nnf6oYG6oSMnQCIk92eqHGgFCmvZJSAaCUbF8EEGry1PN0MFnRTyPQ46jNugZ\nTpzgbB3IsNz3xB7ymu9VsMCGXqzYN/RpV//xiD8RThzA72bnpJO2olO+0ltU\nOA6y21yYHzwWwI2mtJbMO2fUdh/HeNleSC9uZ7taxVtrIvWDO/F4sANnYmZL\nsT8MPmWpJez2sHd+Pc8PYJMxd9N+2ltzH2cQXw8I48jd7bZkffRzIwMP4UrQ\nOqHnxG/tuG2EdqvyeiZ1jbTD9+2OV/63Xy6lBKzbqIkDRnYBxdUkIdJ1ms3i\nMxocvu5tNMlyMW9zdSqAV1i808xjExAAMwQNMxCkMI99gJCJdqL15/iuXwaR\nMqSFL9HbiftX7XlpK7tELWxq14b74mIiZgnbNVpP4ZBMzOkZrbkrgraoqCCS\nRoB0iRaHwjaWhtLm++H5DJNHV/17mdCkUk9wjYa69qaxWj3ZY5i4Ll0xX4NP\ndXdt\r\n=vPPL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDAqUyVW20cdksr+R4bqC4MAqQHVF0EuLFCXKmx3iI9nwIhAIixJzNoqAioNOKRZpUrvzs6rtgSO7x8QPTyF5o7kSta"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6359806_1638291144417_0.36372816302965827"},"_hasShrinkwrap":false},"5.1.6380181":{"name":"@metrichor/epi2me-api","license":"MPL-2.0","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","private":false,"version":"5.1.6380181","main":"cjs/index.js","module":"esm/index.js","types":"types/index.d.ts","typings":"types/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@improbable-eng/grpc-web":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@5.1.6380181","_nodeVersion":"12.22.7","_npmVersion":"6.14.15","dist":{"integrity":"sha512-LNdEpNRTABUp1r7n57laewpKSFw6aKjBEepV+AwOlNV6B8oGboY8LcOB1y+2K4PkodlII33zFVPrlTF72WqL8w==","shasum":"23d981d56161ce280aa069e8dc742a013fee9120","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-5.1.6380181.tgz","fileCount":272,"unpackedSize":4615624,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhqetOCRA9TVsSAnZWagAAAqkP/RUP/cG8UyMs6NBY5QGX\n6E46Q6Yffxu7W5TMjDFOjW+DQpjJZtsXDMM4Pu7bCIwMtM/FHRNjQrM5jUqd\ncGe9ztdIrcHvKBtmCcengJ4VtkioPlDsqC3vUqYnnNbPqevxQjF60M3bpI4l\nnnC/Tn7eFZ7jl4FPRwQc7CBfrV1UL1NyyCEcXDLaKjijOtXTOnKr9VKjK3xi\nWPyatpXQ/fyZF6UhSEXyJTUWudlzSLpud/0BYUuLWFfvPq6ONkhBHbBsJHBV\nk3UK41tU8uNBqAHpjsZMeChOrZ4e3wHAgDK8Mq9NOoXdcFS+MtdTomi8Ejzv\n/CZQrTxmoRpAIduSuYHIW3qeWeWSw6TEdYUBlo8BMjK2LJk5bpVcyM3lQJaN\noYUKbtokOtu8Zumy00Ia+lNM0Bx9Z92BUZB1JMyqGUni043u8gmYaTfXM7NR\nkkR1goojZ0aFPK5/vbuVxdzL8YtpNUdLt544WT7tsYv90RnzCyVwOVkmH7Lx\nzycP2IpKQ5piaQQyxsFpvZCZ/eSYVOP+61AFiCiWYur1uWy4k0eKs5Szo4md\neUCzBGRgHaqhbOKMaacq5WRRQICKUJveGLOTSxzZqpy7CdP1m+Ec0OmySPvV\nIxe2xSCRu0I7a8QDROdZL7XP0IPfaRuzzhVsEngj99vQ2LGuQ8dJh69+PIMK\nQ09a\r\n=Qljd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD1xAa/zS4yB1CTxfUSDM86e0nze4RZ/M8n3HhTlqFnJQIhAJPTkd9eMmTjErn1eUDQbLsk1XZu49wISyusIoLdnOnx"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_5.1.6380181_1638525774703_0.77593673275441"},"_hasShrinkwrap":false},"6.0.6390813":{"name":"@metrichor/epi2me-api","version":"6.0.6390813","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"4afa7b901e4932615a5540ecd846cafd9ceb4299","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6390813","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-pYJLjNg55kN0w3P0YzQE7jMlx81USmD0Eybp9p5BV4s7V5VcJj0Df8hyYQ0ioBU8FE8b4O17yq5b/JSFvKeRlg==","shasum":"98c8ee6ff218aaacd9f04857e9851e38014f3957","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6390813.tgz","fileCount":436,"unpackedSize":950773,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhri/CCRA9TVsSAnZWagAA0wkP/iDBsX+de26vSo+XOwbw\nnVrGJa3ECsvqvOWr/QiqoJPKhfutWi0vLmUP5whM46CoJTglnNIjFXYdQX2A\nDagMUYndbPDd1SYDavtm9UVdMZoQMQpjlpAEXGJeO/3+8PpQ2PfPvHUJ6tq3\n5kz3aoDHSSec84OBFOklFTGw4EZew71d27u7MyC4bNm68tO3RtgIo61jQ3tg\n7SWfEP0Qanz1dEFOcFS8czv3frRUuWsG3MuDLDu3QtPu60xvvQ1yfJCHhQ8O\nCkNGy1rKd8nCcHg06u7GVhGkDntsPdyfFDZhJfMTEz1bb1r2AID7rtz7RK8D\nhLkeEtWSTqRcDG2uFtMEcdBfXmbvHqenqc/Pa/cLBPycrGl+03arjqQWc124\nVB1pKeImDQ3af8LBhRk8P7v91CTYwSUoTtlIgYDFs1tbEbgb+6Gly7iBSfb9\nepqDXD7qwI4ae5wYSJsaZKKZMNvNv3KenDwWGqond2jwh4Z4t1QfFasX6Eug\nGD2gTozYxXByR1X4kfGYUTEHtb4XANn0uhUvfKYvAj1VquMmByFqq8Dagf04\nEHyPGi6iwhfK5vO4KCYl0+SvBkrn/au0mdqb1j7BTKJld5oPmVqHoZloYwJA\nlozfKOV2969+wEiJ46AhVm58WBwSIDddw81iYwYC9U4AGBZYlORvfot1Olp2\n1RQA\r\n=hP4y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD0Hwlh2c28fULx3D4ixF/h6unTi/eutAf0PF7h6h0zVQIhAPdUIs/0tCZnGptbTEjH6LMtqu9Q/kwOPZkGY6LJUcyk"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6390813_1638805442617_0.3018695120315311"},"_hasShrinkwrap":false},"6.0.6398206":{"name":"@metrichor/epi2me-api","version":"6.0.6398206","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"71e381452d2890ecea6e7bef4bdc05edcd0e3f84","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6398206","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-/SkvXa7/LXlr0CnwCiqwDlKG5BD+ITKppe9Ty1TvgAydcWsIZf5tSUwlxvQLMJG65vZ7ip+o1HKI7XDQehjPLw==","shasum":"6cf2a1ad31f9e5206e512c02b8a4f02ae79fb3ad","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6398206.tgz","fileCount":436,"unpackedSize":1399840,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhr5vOCRA9TVsSAnZWagAAMiIQAJ4rBVW9M39VS6/+EBHG\najpD4QBzPEILeyVfIA1XNnuxliwcHFfaEpcM8lRDPJVsbj2agerlqiddaQZT\nTvxJXb4eoi2QH0anb38GSJG1z4BWRa35w4TpIFIz0t27WM5fmDGEjNYTfUKh\nCcRskPxGO5/5lsyuLxec7xMLoVuFTw0I2925+IQuOHcq1rbr7zYyDKdyfebP\n5Il/qvq8EIURdfSJ4UcX2R4dMrMPOPwQXdK2x6L/A3jGeTvBxpHo/NPc8jjj\n3qrp5GzQIvJmmwxHsVbmJAccdDbDDD6IEmM3lYP8/VnsqYSO4NSN75zrBDGm\nW87UUv/fqjO4La0BdulELPuQFqonbUihTQMcUARMobmsEiKc5m8Luk5DOI3y\nCwuNQHnoXaSvkq6b142D6s7cqcFgsDIFxusj+uT6wJezaSFabnTbPDdmyIvn\nEaTA7yjwc1rbpO/uF4ZRi57c9CLR9EF8FEdDMZSLH1XDJn/q9FHg6jk04Zez\nrxgtsNdLCOsoc5mMzI8y1qkcH/zS9I04rpQy1n1zFsmk2pdJKddf7YX5DhKp\n9MoVWQAtyFbhYWsfqvTqME6jfc/RfCvtkfB/04djHkbVi6+V/zNIdFKft1Ir\n2zqWF1YSRCtsDG0Rs20X8t+koj1+uXqi4jihHwP0k2lgqEarrwg5yEECKkUl\n3oaI\r\n=ed+X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCnU8EV+lmGqHNP9yHYTRmI3lX+dTfNYvUG91PzfQApIQIgKgkrqqAROPAUNS8fSgFR3JNQz3/LsrHTKHqV+seg8gQ="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6398206_1638898638462_0.3560768391146145"},"_hasShrinkwrap":false},"6.0.6398535":{"name":"@metrichor/epi2me-api","version":"6.0.6398535","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"c4ee34c329d6755945410e0271adf1d74818f2c6","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6398535","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-LpzBZmhdheZ8/lrG4G637a7iyw2/O4SOQ81o+Eklx2/gaaoLs4yPIN+byHpSTa74Jt5OvfYIZF/heAn0MgqePg==","shasum":"a81b51b2b0c2278d4c33417e9a2a4fa6aa10da2e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6398535.tgz","fileCount":372,"unpackedSize":807483,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhr6egCRA9TVsSAnZWagAAVG8P/16uVZ/kQCFbD6g9aqIC\nYMzcv5eOl/sefhxlZpXJlfr1Wl9RzWwJoJ79CjndA3rf/6ZX3Hkt+zCIwUQr\nzSP5qt47xV3yZQV8Bvf+oZztDO81zKyXlULO1x9KbD8Z9OVuVWAMi/FVL1I1\nyJKsfo4U6tKAbwI3qIuB1ylvyC6W/7Cj1l/N+w7qX9RzYZ2NIODxB4SctujL\niBk2ce1pJU7j0USRQ5gPXfkZvNadBND8JA072aoBjCPW7Da6wCMY1PbSPveI\n2ohyPTRZ7fOToaNkTSqaL96KK+eakm1xzoSbD4BMBsO/P4iIpHTLlNlg9bxe\nbx5ju9NfDg36vYW5ywtpfyGop1huZ+mm1mkLQyfIhSAOndWwl9q7Mq0YmK/x\nd/8h1210lnRR3RPUdcZnLpegqUjj2V48TQLgcbNx5wDcz9MthbFN/KMT7uKF\n+0Hg3QV4DfNaKJvk1n7hmnb4aXZn9V3ipduG0Mf8iRbP1LNjAUM4JQF8vK9J\notBu/vLBMvTVD5clAnTk4H6qPaP6plyAEwZXnyiLMEftLig/bARjKzm66zCw\naYoBOFVKMs+DeWoxTCk2rRqrY+DLi5DZDy0qT9SY6ZMVRJSWLk81EH2nft0t\n632OOR9paC3G5HK4DJDN43b466/v+/u4dUJhtthGc5N1JHGXSKAxOdTJzozX\nYGoI\r\n=0iV1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCsn07a8fZqf9ZLqisTS8voEWxAmRwXjZvH6G+pCwb3JQIhAK54gWUTyHV541YCko9VNm6gXFirYWbaqV63V2or0U+g"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6398535_1638901664703_0.012957556989715124"},"_hasShrinkwrap":false},"6.0.6403726":{"name":"@metrichor/epi2me-api","version":"6.0.6403726","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"fb00a195f0a995e6e663cb671e9d398d51e0b792","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6403726","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-eLWLvVcp/qLSucigVaqkg94zOHl+5Bg011KxY/JbpkVNKlZgu9myiB/DWnkuyrV/TdYaYBQM8/hM5trPWs2bHg==","shasum":"d81d4c90537858ac0e03377b0866c730200743a8","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6403726.tgz","fileCount":372,"unpackedSize":807497,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhsfPsCRA9TVsSAnZWagAAkysP/i2kA/UfI0UmSoOl8pRv\nE88zHAOxwOEAis/RbskyE+QIQ6O3M7P4bklq5y8teBhqFjfOQmVZw2ch7g1W\nVKOfWiWuAkV2AObFuzBO9rjJHXbAIwP6DHMUMAltKKK0BDdcYy0DJtlHYYDD\n5QbWvg4V27dvlJhaxvSjBmqGZfboZkvrbaUbxKNEbJsISUAPQHheHaiAjskE\nWlMRzOkdKZgfN6I6pvFVXUOXGMDgBaZiYkwr8wM0F+izDklO3B2kaquHChoE\n9VVyO5Kemrs47ouSl4kuVG1Sqn3kylqYGzdGdqhZZlNXig8ZAVJwiFl7qzlR\nappCKDvuPBQs2UT6s0hWd9fSyNG4GwW45FR54TCjIWocREq+HFgc7nUX4s2I\nWsgPUuUfqyeJl5126EATY57TB1JLUPVhTcDaUYL2g9Uh02QOjjYCgNu0sLzQ\nfGx9HFPFjqLP98yJ3qQ9L1omzVt00gacSLgVdYSy+Wo/uGr+hR/FwAOyQBUO\n+oWL1ddDwPjD2NtC54AmC3PfEl4aQrUVglsAESBhdd2oXGqKrHmwZK54W+S+\nYelyVNMU4rafs9sXj67GR9XEHCz9diwM5qpxodJRTA8y418Ay5FlDgT1wntw\nu5c6de0Hs/PqyvQvqo7pM7R8cyrDqcsbT8+xR/vJQg5enxabJeySpAr6opu2\nS/vk\r\n=sOTQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCiOWndglYxtYvZdn2jewkWXJt421qfi1wuf4zM0KjlfwIhAL0OXCRuKGFkdYb3taodJ7vBtfM18Poc3HN3dz307kUu"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6403726_1639052268133_0.8995307864969062"},"_hasShrinkwrap":false},"6.0.6412072":{"name":"@metrichor/epi2me-api","version":"6.0.6412072","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"d64e947de159aa1d5dcb3835ab79fdcfb0b94ce5","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6412072","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-rp+qQyc6HcAehydbEC606AuJp5eEFvHo/OxE60VdZsbQZaO7MES6J3ME1skBEjOfa7ayR2U4nhFkAqXdR7yjaA==","shasum":"31b378c12f0a93199c7c2f52f3410e502920057f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6412072.tgz","fileCount":372,"unpackedSize":807497,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhshqeCRA9TVsSAnZWagAACxcP/3laiC92H38XDjnSOhzj\nyaabWU2aonE7a7K1vr8kC1uMIzSReD0Uk7NrE9VdHftF7r1OaImQZUrcI3Qe\nsYAMMYDSq6RTjnRBYSu7JQPFtD3hX6dGu41/Cg/EhxbAHDj12jw4asVh7vyM\ng8mX0qM62H7KbRSZ91o5WCjAvZz/VxJQJOTRi5BsH2zi0XKvOCZTH93nIgR5\nQEvyLETVJIq+n13rZS35w33Cu5WDJMgk5hN2Zmy9oCiU3bH0ZKe/zhl8O/DF\nKv7bd53kXiEv01IT9y88xcZ/m+QNdp1o1YKjBAhRQayj+OltAqz2OXYsLaBW\n8z8xO+tyrDUtb9QXy/otwk86n1rZT1ReaWyUSoqGFBbu/tL/u4GdgBuR73R4\n6wbxTrIOEu2EY/Cv6wX6sFqesl6SuOarbwZCXmyavhbH87kihKFopNM0mqZw\n1lhFkaCJPQtvy7c462kkTWSutblGo6ovf1Fadbeb+9GcMKu3E3m/4ZO05Ofy\nlxm5VA/DtD0pqJJt0yL9q040AZhn1wMpO2w9xQkWqcgeaKiX6zhOhE52N22n\nTT0zJdX/pXNJSBbaRI9wGZDgow37iuw9TZ6H8yin2ewMtVHKVVNJP5W/NunR\nKaUjTAtiY5smpFS0nYpJS0NsMYAmfmFuGdZwBFvpB7vKOAFpRsLCtF+wl3Xz\nTZlQ\r\n=mhiD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB4FkVAlpcNQXQSvhYvLXhY+P6QZ0IlBED4F2eovu1NdAiBxlPw9wEnHjnEO6eWEuiAqUGHHRgyGE98UzOnpAp669g=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6412072_1639062174183_0.8150206809276115"},"_hasShrinkwrap":false},"6.0.6532891":{"name":"@metrichor/epi2me-api","version":"6.0.6532891","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"9e4abbdc57774b6f78e27f2cbf189112844cfd81","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6532891","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-Z56d8xIAEdyLJBMAnG8geRWCYq2jI4LivOj0COOLllpIWhl9KcHjdvIUALVXRaSq5LZGwS/qG+MyUNyOYycJdg==","shasum":"76345b8dd5211c4019b9cc2f66e76d7123264906","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6532891.tgz","fileCount":372,"unpackedSize":808503,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1daMCRA9TVsSAnZWagAArR4P/2xuUVBDuisKfBtOO6+J\nJ5goPXgAwySRjDj8zonh9Y8EY2OARGt5PDdleOQ7FB5BjAnTimZ746B6y9di\n4cKZYqjbroVjiLrveObd67RbTRnhB7SRDfZZgpIRP2rAT8DQ+dVFG5xV2WRH\nXmajYCl4x1/KFRz5NYq4fRa4GlCDvQKcQeEjABdhB+Om/WxmYg/yZdt1Kmmm\nB722cwlZ278Ar0F0WW6Dm+IgKXfvD2UFsFSHWWtUz8Ba0qGExyASyYAVbGek\nFlwYz551oLF8c91VLYHPd4D0M+gZSWMdg6idoAL7nDe5oHOTse0g1D4844vs\n2pf2Fs4RFpB+UNqLGA5OHoybS+Wtr3gPAt7XVnavEQQGxMrn4BRBmGZt47WL\nUL6laqRIGl1JZ8suYmAMawQRz5Wgz8qu9A2ml7NWIkAJwfpUCcCG4IwtbnzF\nX42qx0GXFV+BAYUghpC5WXyq5yLw+MMMUsdpA2HFSavjIInWBGb2sEVe1wPp\nFEfoWVak3xdSvnyb2SW5DEvi19Bmi7frGhyZjP0yB+rYfpzSZPQHy/blOjQf\nwlEHbIKYVdDoRzzm5YpJgFLj17+44tZ425fESb+RFTvyS+WVUEwTm2XdDFet\nilX8MsuuqXRlPBQLFTA26Mz6HA1OW4CMJs5oaJAuepWJ0k6d04/cuJ+O56kt\nk1Wo\r\n=WJ7Y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHm8FJq45YsqYc3nms5pEGL82G81oFpT4BrhB6YrbukLAiAg7sL53QBw8QFw5HS1XagytkJF+Y0oD846LfBUP8NK/w=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6532891_1641404044047_0.480378903448929"},"_hasShrinkwrap":false},"6.0.6532936":{"name":"@metrichor/epi2me-api","version":"6.0.6532936","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"gitHead":"abfeb7793a7471a494af94a2fdbbb0d9753f2138","readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6532936","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-8TnuIWZ/LAOg/kbZI1S7DGUf2zOPnYc7AS+mK+veF31f8OuWaIC6CpIGlwk2A5Ho1mqHHO84zpurfaO0qpSJtA==","shasum":"1f79fd374fd9196040c2d12907375e6289723e71","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6532936.tgz","fileCount":372,"unpackedSize":808503,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1dgcCRA9TVsSAnZWagAA7f0P/0E8KuSym00Bl4QYHriN\nGe7/dSdHLHBcXLDRjqQr31Vld1uJYOziS43e3ADBKxd2Dl7/Se2nE+NBhMHW\ncJRosyRzdB8H9iiGjj8XvZCf6gNBgmRD0kVpY6u6P7j3uL2bdEX4GoJYhiQG\nG7lYtej3Fi34uut+B29RZ+mtSZ1PWXurEL+R1uJ7Ahgq6KJGsGBkA5obZ8yR\nb2AkBMcC7VOaed/D6UURngWCJKFgG1QijOIwEekstUbowWr8KLsB1hotJdE/\nm5kh19mFIgSkkTr7KEN+DBYxa3yy24qoY53ee1CYzYOGwMapgOb89y1EHWhU\ni223zKlaC3Fg5QyF4tyao7pgKKsbWYpYdVvqiiYeoLUdbHuqzbYVCNXLty/U\n/8NU1f/SPjIxjOgAiS5KdLuox42Qi+4s8Zt18wJkbRezhn686A08KjvK7ykT\nLoyYAsjeNXCGzS0zxUdNze+6RHov0GLOZAzRAvLdUVXlHB144IallVNnyFsU\nwRSPMAIm0R7+aNXVj2bBy8+ZvRHOFKP7i8diNk1hIBmgeRlam4Y7SQ6qvC+d\nF21eyA3trQeuVOLN2Me8azlY2fy0EVZRpBUzgAzUNwOufizXTZY4C9eztyaK\nP9h6zlD4gB66vMyGxnXsMHCarDuq6Sz9I0gkQKfEj/Zq/gsYNpbJRg5yOqcN\ncyLP\r\n=84Cv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQClbhN6Z0tJX3GDGDEjmGz/1dMer0J+87TOswJFXwMwhQIgVolfL5pX5XkQBfmzw7ccN1p1Q+nq2867pzHpWb8vDgI="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6532936_1641404444322_0.7865349248632916"},"_hasShrinkwrap":false},"6.0.6905467":{"name":"@metrichor/epi2me-api","version":"6.0.6905467","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"846cfc357493c5bb05d51b7ea0e38cd3d41f3ca3","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6905467","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-kOrZYHS7cU2NrW/R3EoHzevNtEu6rN0+87J7fntxpk1u/lqSYYrxu6Dngn9+qN3yLJox23WjIc8TFcJYL+qaVQ==","shasum":"6a31f10b2baf7c27bb52fbb6e26eb887dca78eea","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6905467.tgz","fileCount":372,"unpackedSize":808509,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiA8n/CRA9TVsSAnZWagAAwXYP+QF6Vvt5yYO9Cn+61lB5\n8+6V394lZ4jCRGw8AwYBCoVn3ZbKwziU984kO/JDcIAymvPYZWdTZs591Eoo\nVKhJKwyBfZmMFGNY+zDAx5VnDDVw/2O9h/fM4iORaLpysbsn2ALlVIN10t85\nNtq1e8RpzQrhaFSFt3k+uYSiH4jSbi09BS5ApAwKhKrY6j4RtgXHN4FSq1iY\nCMB1wFtp++cpXd9hv/izCb4YDGHQTcryWWER6Gg9gZhfY/PMiTxOcm3Z5PoE\n7wrm77Qt02eG2BfVJHviHRyV/eueHAMb0CfLpcl/fSfj/rzy61jslK8ONh6D\n21rbXoRk5MYy0M9u9zeMEPV9mkGmLIR2uK9Tfett8zN6cZHaH2zg63Zabtf7\nIB3I7Olr2KB4FYbMMJduPI8KwfaVIH1IcDevVCP8ZOerd51ppa4j4rluKRsd\nxV9j8b7XvrSbwxF/uskEzdfGlHdmOJ4yRYxjkfzumKpz4nkUL1f7uhggVdJ8\nmisiebPeWS8GA2BK9ENBzo5FpHdreCkl8z2Fpmf+PK8jaaOCJU6CsMY4nF2D\nrmXRxvOnTCpEWbiGsEATrdXm9G3ruT8D1iAVteeBFVb62uKIqZkvS1ncPyHk\n+ho4AOZNHrtp8pVmXL9SM4N8OuXnvM5G3tGTHubXP3yM1po12AfgsY4Pxy2a\nlnGJ\r\n=Iix4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDfN0tiWjkRZs1t+LjdDu7n3Lh23FD3yRpfk4CNg6gymAiBCQ03BWoKIibtYpcKPq9FW6QLNYU2BdJAs8ODM4znb+A=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6905467_1644415487602_0.5159180237206302"},"_hasShrinkwrap":false},"6.0.6966242":{"name":"@metrichor/epi2me-api","version":"6.0.6966242","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" align=\"right\"></a>\n\n### Getting Started\n\n```js\nconst API = require('@metrichor/epi2me-api');\nconst EPI2ME = new API({\n  url: 'custom EPI2ME host' || 'https://epi2me.nanoporetech.com',\n  apikey: '<your api key>',\n  apisecret: '<your api secret>',\n  inputFolder: '<folder path for files to upload>',\n  outputFolder: '<folder path for files to download>',\n});\n\n// list all workflows\nconst workflows = await EPI2ME.REST.workflows();\n\n// list all workflows\nconst workflow = await EPI2ME.REST.workflow(workflow_id);\n\n// start a new EPI2ME instance\nconst instance = await EPI2ME.startWorkflow({...});\n\n// stop a running instance\nconst response = await EPI2ME.stopEverything();\n\n// stop all current uploads / downloads:\nawait EPI2ME.stop_everything();\n```\n\nSee also the examples/ folder\n\n### Constructor options:\n\n```\n{\n    agent_version\n    apikey\n    apisecret\n    proxy\n    url\n    region\n    retention\n    telemetryCb\n    dataCb\n    sessionGrace\n    remoteShutdownCb                        // callback for remote shutdown of\n\n    awsAcceleration                         // Use AWS Acceleration - boosts download / upload speeds\n    inputFolder\n    inputFormat\n    sortInputFiles                          // MC-2535 - sort files to be uploaded\n    uploadPoolSize                          // Parallelism of upload queue\n    uploadTimeout                           // upload stream timeout after 300s\n    uploadBatchSize                         // Size of each batch upload\n    fileCheckInterval                       // Seconds between loadUploadFiles()\n    downloadCheckInterval                   // Seconds between loadAvailableMessages()\n    stateCheckInterval                      // Seconds between instance state is checked in EPI2ME\n    initDelay                               // Seconds between loadAvailableMessages()\n\n    outputFolder\n    uploadedFolder                          // folder where files are placed once uploaded\n    inFlightDelay                           // wait 5 mins before resub\n    waitTimeSeconds                         // long-poll wait 20 seconds for messages\n    waitTokenError                          // wait 30 seconds if token fetch threw an error\n    downloadTimeout                         // download stream timeout after 300s\n    downloadPoolSize                        // MC-505 how many things to download at once\n    downloadMode\n    deleteOnComplete                        // MC-212\n}\n```\n\n### File management\n\nDealing with the large number of read files is a considerable challenge:\n\n##### Step 1: Input:\n\nMinKNOW batches files into files of 4000 reads by default. The epi2me-api object will scan the input-folder (including any sub-directories) for .fastq or .fast5 files. Because of the potential strain the fs.readdir operation puts on the system, it's run as infrequently as possible.\n\n```js\n// trigger fs.readdir\nEPI2ME_api.loadUploadFiles();\n// once done, it pushes a list of new files into uploadWorkerPool\n```\n\nBatched folder structure:\n\n```\n├── inputFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\nFlat folder structure:\n\n```\n├── inputFolder\n|   ├── *.fast5\n```\n\nThe EPI2ME api supports both folder structures as input. If the uploadedFolder or the outputFolder are subdirectories of the input folder, the .fast5 files they contain will be excluded.\n\n##### Step 2: Uploaded\n\nOnce a file has been successfully uploaded, it will be moved to the uploadedFolder. The batched folder structure is maintained:\n\n```\n├── uploadedFolder\n|   ├──  MinKNOW batch1\n|   |   ├── *.fast5\n|   ├──  ...\n|   ├──  MinKNOW batch-n\n```\n\n##### Step 3: Download\n\nOnce the read has been succesfully processed in the EPI2ME Workflow, a message will appear on the SQS output queue, which is monitored by the epi2me-api. The output file is downloaded to the downloads folder. These files will also be batched into sub-folders whose names are completely arbitrary (and set by the metchor-api). Note that these names are not linked to the batch names created by MinKNOW\n\n```\n├── outputFolder\n|   ├── fail\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n|   └── pass\n|   |   ├──  EPI2ME batch1\n|   |   ├──  ...\n|   |   ├──  EPI2ME batch-n\n```\n\n###### Notes on EPI2ME Worker Folder Hint\n\nThe EPI2ME Worker may pass a specific folder hint in each SQS message (SQS.messageBody.telemetry.hints). If this flag exists, output files will be split according to exit-status into either \"pass\" or \"fail\" folders.\n\nThere's also the \"telemetry.hints.folder\" flag, which is used by the Barcoding workflow to split files by barcode:\n\n```\n├── outputFolder\n|   ├── BC01\n|   |   ├── fail\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   |   └── pass\n|   |   |   ├──  EPI2ME batch1\n|   |   |   ├──  ...\n|   |   |   ├──  EPI2ME batch-n\n|   ├── BC02\n|   ...\n```\n\n### File-backed api\n\nYou may give a file url instead of a portal url, in which case the api acts in read-only mode drawing protocol workflows based on the url given. (This is determined by the url having http at the start or not)\n\nYou may give the full path to one protocol workflow file, or a directory.\n\nIf one is given, then workflows returns an array of one, and workflow does not need an id provided\n\nIf a directory is given, then workflows returns all files in that directory, and then one of these can be selected for the id to workflow\n\nAs this is readonly, if workflow receives and object, it immediately returns the cb with that object;\n\nIf any other methods are called, then they populate the error argument to the callback with a message.\n\n\n### Development\n\n#### Updating the GraphQL type definitions\n\nThe majority of the the GraphQL types in the project are generated directly from the schema file. To update them replace the `./schema.graphql` file with the revised schema, then run `npm run build:graphql` to update the generated types. \n","readmeFilename":"README.md","gitHead":"ba86f7f72286f9bfaf3da6c02e6f576b9142a624","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6966242","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-wcodcaj3tYpXhRx4+Fjo9XM8SxyD+DfT0Z1jjquH/uwZWT8N7k2IKsJicfrd559dIFgDGWITsHOCYnQwgSQpxQ==","shasum":"65caa8602e69502f35783b51933c62bebc530f33","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6966242.tgz","fileCount":372,"unpackedSize":808641,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiC4vqCRA9TVsSAnZWagAASeYP/2K4lm/v6dObErXu3ui4\nN8mJYy7DZ+Wtjx5J7+K+7OpNKE0QYyByRJLCybPAHOf/KLTFQ66BArBfojVY\nrT0/BBxO97+CG6qj3RfeceRi5klbPR8EwRc5ZeYU9iHrC0RfOPVUISZQTPWD\nLlF6R4kMnlPpVtEfpkfeoSYGliF4ux7c2/NaTLQkzdJ9Q+WPYx1/VIFDUWr+\n5BxrDpVrkyy7G3O8ymW/g9e6/spGGGYsHprLrzt8LNtVQefMGC1i0du2wPDI\nlCnZUuRerwM3p5czeSVblhtJNNG6zhBYUZT2TyglhTqVqt+dv79MX0mxOrnD\n31ZxloqEW1pHfHywqSmPjRbGIEgNE3i9Nnjn2/8u2HRLs7TB6xIJvvZxA8DZ\nHcQcHrN595I3LgXLWs6j6qn9GKQceeCGnhmD81dJly/gnP+Hp4LuBnd5V8jQ\nvcwFc6b0edL+rJTsrC74JZ8vLIIXyIU8IYkOfbcOUkcUyURBX/WVPbE2jeDY\nYpc+Bxx4ERcR0tL+WZkIc0qrIgOPSroLNsIX77+ab5PDH4thNJyYZwNYIbUU\nfEVhlvRJWFozR/Hspa5ibhVhd/AFHV98kpQ3QowzD9RvK4hrpZAFfLEukdRq\n9MQgF7DdMGY96wFPaA4W6CqEcBUOk9eQHg/pOKQ4RnrgxyO7yMpZqf3EbTpN\nGfky\r\n=MEHq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAvw5LaeAmTH4tHPMqC6nX9TMA9+Txo0ZWTjpH4mYpwLAiEAs0BbboqSqeyo0Y2nyUdvK2NTNssBqtyATt9D28L9JMo="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6966242_1644923882109_0.0007081044024259686"},"_hasShrinkwrap":false},"6.0.6970419":{"name":"@metrichor/epi2me-api","version":"6.0.6970419","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"9cc00ad5a5eadcfc39d2989ff3365dbd359462a3","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.6970419","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-ygqOzKKRsjXJHshC8L04t4ezzy9aJZM86GsEkMb8t6qVpDYTNaRo5Dt+Pm8CNECfAFF0KHYfiT+jAF7ytcBVeQ==","shasum":"d033d944aa5897f259e5395de70e5581f2831424","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.6970419.tgz","fileCount":372,"unpackedSize":818924,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiC9BgCRA9TVsSAnZWagAABtsP/2YhHCp6zsJdJLNXSqj9\n92/JySJgj845Acu/IrJrdPlSuH/kTuyULNwa6XNZ9qUVboDq1cWK0/w8dUvf\nSZQKL4VfiDEajWUKrZjQ3NU4Ajkw2i/hsX/ZgpYs5rVQQ9FQzhhst1XEaw/7\njNzVVKvESieaMuJhW2d0Bb+sfrwtCCJQZc2AADfx9kSXMV+/3K1NabyhoF7G\nKJnnoR/kBODjao9DctANqwrAyvbxVQutMM+KyvYBHb3BGNCov91zk6NCsBgy\n6kwVAzBJxsUc5Wh0DqhGfiiOuzVb3mukM8ZrOdnUxqEIPkN/aK8y7Gkil4ft\njrJ8F2h2kDsHu+YNHWfu6Px8/mOruvJ0ieLyyNClQeFl+/obFq7Mgx/xx38y\nv9GkaUmS563p73R0+8nUUeRPIN5mkCxZ11ugnpuPF6JuCFkE1uFmplcMUcYV\nE529oRLXy+z0Ln15k97ZAWT0Po1redY14gJQKanEOaqmJrTHEVL6ImIOIH60\nFrPaT8Z7F9wZlW+xR9VvgiRAPcqRp42l8/0DInCJW9SHjuxnjTiP6xKf6sl3\nBJQ+1ekHgZ5IBmdLWFQkzAl4TKXOs8aygyKVOZTFJEV5fmuLlihmzblUL/NB\niDzNFluU42Gp1nBRuaWAF3I9KV7WO0G4AElVqVUZjSKF1eZYphIK5ofQG7wj\nCRE2\r\n=pq83\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCs4Y4O5HJQMav+pntpejmpG+8h8iGh0Z2meTqRx0xT0AIhAKE6U2kXxm7O5d29YSyqkD89n6Jrlagz9lQOoJ1xG5cN"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.6970419_1644941408360_0.4293340247806099"},"_hasShrinkwrap":false},"6.0.7043994":{"name":"@metrichor/epi2me-api","version":"6.0.7043994","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"52289688d8cd803b0222a66813137941334fdc5e","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7043994","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-XadkwrkpH7CAooi4QBbnu3bC2j6+N6YTj+AD29aysj4sqT4Zi5S3DTQlda/OpOlL4RPMbzIBaOYwNxInPkyzIA==","shasum":"c811a59a13d9f0176d7a08e112a0a6af7b15eeab","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7043994.tgz","fileCount":372,"unpackedSize":818924,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiFRf3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpdgw//XBEfy3Me6IJSoALc9yY+LS0lyMN6HWenupf8bXChEmvZMEjn\r\nXLbyTvmKl4yxnbb3OMwBXZvU/AYdkNxo7Y0zARrsWRMgwe54Z3h/owzF3LYg\r\nA9UWfuSGTn8uhiPf97i1zKccV61zEIHe5ZyL/9g5q6N5R1j9qcJV5AeQ1T9Q\r\nnRc+keQa3BfrWAryoy/iXdhihnPr7c441Q+bbPn/eGxtCY9ieXwH3p6cV7+j\r\nbVbcCwiphLNFI0tUOdgqGcOQloOc82XFzmhhQWKwyPYgysUkeOmIMVRzgkbV\r\naT4WikVWz2K997ej9XDn9P1JVTBdP30iV+m/S1fqI0j+3vpSL9sQF978yXTP\r\nqoTyzThC0zjG2v0PjF+5S2b9SHx8/8ZoLkNqjnSHUEU4yqEwNYt23Ha7rWad\r\nzCeTJBaDZTrcDc6AavLzuKEv6B57tn3La5Xg5XPmrqe2KLBpafQYv9XWj7jg\r\nPTs0oipuiFteW8CMy+SOWZCsBNLDGIKBLpuWMBSofKqzM2avDAoc9X6+AB/K\r\nfH/oyYCcYxOks4mg8IEH4T/QqoIOjM1XO4j8+DYx1I8YASqlSU2xYOnRzwXk\r\ncwEC5P1hjoLhr6GR5DRLTkPnY0eauTOFabcWBto/rzbZBSYjWfbZ0QLsBKLk\r\nl1LRiRxxbVTID8F5KykvtFychzyQNJ4Ka9M=\r\n=dqFC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHE9gp54Pl4hMrpborzhhXZYfdGBpG6dtnJIbbzyGiswAiEA9RqHEFSHFAKxXywgDvxC96AXiVFiMu9uQ2g6ROeXczE="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7043994_1645549559437_0.5169722028822017"},"_hasShrinkwrap":false},"6.0.7044474":{"name":"@metrichor/epi2me-api","version":"6.0.7044474","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"e4d4488dddafbf1569662cfc7a81516acaf5889c","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7044474","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-U4G9DTNUA4zDtooGVvTavRXl9bKptmZ0uCKn1x/qV4usuQ7gVy8iL1bivptIqpbAv7RUFKjxq0d1kpWFAc8ckA==","shasum":"b83c0177d071a12d6cd898a9e2cb68f9ea5576c2","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7044474.tgz","fileCount":372,"unpackedSize":819645,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiFSZbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqyWg/+OIBQKXcoGKCRrZiaCL3z/cS1XvIN9N2DWPMdYwnTASzRVc4L\r\nvru/9DdJC4NJBnmnocDAF82HUbykEYZMXzOT60Hntotn0XDhRKKYm9yd4AXu\r\nDLV6WZkqepGsR90YQleY3g82KlSajoLzP4qwqHhUIISkc7RYzcHeMXK31NZ3\r\nW0eio5ANv+4rG601NuPSSx/EX6tz7xlnP6XXxM28izUFOVzOgv//50/YgpR2\r\nxKn26v5u+ohLQUMO9haZjMtPx4pGeBSD8pA2RMw20sAVpGNgTKEnvT7JFCm+\r\nsi9WmslkZEA2HgL/Rs3lIaYC/FSz89vUbeOh865LjMVkV/vbcUMIyU744/Mp\r\nIJo1hYBvfy+E9uYsIcKidle13asGSld1Q4dlrLB0KJ35Gg2glU6VFHLzyFpm\r\n7ZNTlX9MihX0Wf33dIdRJhdMks5jpCoUfrbXuTPygmFHfCqqdYDagDCk7ngL\r\ninWHu1CEFTHCAV1eM9P7jVAazG+wtfcteFTVpnwNhzlvsvbWRoT5gX51SZEu\r\nQJFldwr2PYdPwo4XF02N1GbBbNsgyIKhOX/6zC23R+4IVJInF69mcASox6VZ\r\nDIRVtuOUJTAtip1XTBmKHSnedufCC0a/GhMDcJyurqThnWuP3gsYIx6C3f/5\r\nnhW19bxd5CkcuFm0iSrSSGph3EGoIVft2Dg=\r\n=I7Um\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDv4KM8iFFFV74ZM6UEdwg5bMu7Bx104BIxOgVm4JaabQIgL+239BqIxIAHRymYlBLZY6bbQKVN8Ad+P+FVwlUMCDA="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7044474_1645553243371_0.41400096858651025"},"_hasShrinkwrap":false},"6.0.7044626":{"name":"@metrichor/epi2me-api","version":"6.0.7044626","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"32e0a6a0da805b36f21818cef11767120cc32e20","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7044626","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-0zNLY/wdELtk9bnDXKy0QuxZj6QFOZ1leDB/nhhWsYMnNMkitHXFDYwyf1Oq3Dl3QNQYEAMvy4tQTlh3AOgWiQ==","shasum":"feadddab6a3cdca743910e0cfe2118f6d5ab4118","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7044626.tgz","fileCount":372,"unpackedSize":819645,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiFSfVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrWtw//cw8eQc52cr2ZjY/aSDwi7jEqblycEyNWuVCMX2zGx1/dI4av\r\nrLfKPXQaHZ6rlD5z0uzZk+8jwWcABBgrcdxeM/RaCBSTllclCwdt9M5C6m1L\r\nwcfkOWY2y90vEyY6M/i12FKRQhmUZLzxBg0OGfWYjNrypdXMIWShGzFMZlH5\r\nYaZXKcRV2gUCjxNDHMDyQ+XAl8hUSsdwrepVM2L4lPrIdiaa2fY0HnRJD762\r\nvc5eF0ftYlN8i9dfR3OpJUEQahTlkik4USNz7ajXen60Ep4lD/+e6abCy9/c\r\nplfbWsFwMGZLeCHK9zQKaSUeHevfADtTXBcYjnfBwxIBQPusTCHoTzZKILoi\r\nIY72TvqX8nDYCuU/OrcXqIrGNRJiMLsz4u2rOitiqzmFS4NsQAHR7SJUTa7S\r\n89V8Ux/4H0GdTMw56gQYFAiYa0NDSM/U5bx4dprGOlrpqk7xBHGRKK0hXCW6\r\naOSAwKJGUXNJnNLkmYwEpPMZJeX/iWYGDMY9xmvj4pyyIx9Pj0+cgXeiTtph\r\nJ1rIDHioeDcIM+WE/ktZeT08x3Vi3bUjAO6ubAwTVr0Id3gbTpB7K3BbO4bt\r\ntkleuNhb6skEIBbotgJn8VRoL2IesN0ebwClNbmDWHDjsYAMP7bnuMzRMdeB\r\nozvQ37cQC7+qicRhhETKk5ir1HVGWtL+n6g=\r\n=gCFd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDbogWEMHO63VzjZ8whn2EL3c7/lzHJiwu7G/7sJBnUlQIhALhZyDLsYwAVEEMVfWm6Koav/oQhXBcbXJ6VPk7FwmQm"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7044626_1645553621619_0.5570162250925532"},"_hasShrinkwrap":false},"6.0.7044649":{"name":"@metrichor/epi2me-api","version":"6.0.7044649","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"e2f7136adc6414f7d048e94f9f232bf338953454","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7044649","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-g7+aMO/iO9JGSliumIM52yhebjSobYe3k+OaVLFvM+boHd6Uv9Dv2EwLpSOywG9GSt6NoTAWk6WDLWmPtvTtlA==","shasum":"c4d464a3f9996c80e1cdd52a1b9bb9a02fa1526a","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7044649.tgz","fileCount":372,"unpackedSize":819645,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiFSkCACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqrrg/+PsDqL7Pd8giDgB+njUTOhRlr6YX6/+vXv/9QEPGnKHy/fdOc\r\nFZbDRhqo7JLRS5dU1GqTuZys77Wr+sU8PQV4ohe9lcBUUqkRspNnjtUD/O5H\r\nCR9OjAjYcULZYzQ1snfI7FtjxawCVAWqaSeSwb32TWThKWl2FAZHqGeNQtD2\r\nMB5zaj82t9zcyCgdojSyBOUgwmpB0/ZfJlK7osCVNNwyPebVflpbfMrvtzmx\r\nFfPitx3LqtG/Y5fZY7yOiRMJjRjqNyLLGBV62BXRVm7c0W1agWhsHU1Gso/V\r\nVZM7PA4zQz7ccPqPt5w2+uihq7PhSNZkZi690/FkB7EHLVMaCCY3WsHrymTt\r\nYKU+qeqFNEuXtFzp/COSZYZxjoeN2mGCiQ3158heS6iU7UQXQGA+/apsDipf\r\nnKvrRXBJ84tAMp1U7g7u8h5LhWGUCCTCSDKLw6ex3szrxnEq9ASha1zlscXJ\r\nGcd+Eyx8+ZaKoOEGYl9RnrooZspHLdlluqP5utIfGG1ymavGS5Ny/Wxc0Es0\r\n7HTAKsqTsGE4Pgt3StLRoZpP/0aV1hCnymzyp4pQ4UMxTrJb1d9PzEyxgYXD\r\nMvHEfV2Hi99t0QRs5P4WaHRqtvBc98vIIHN09ZYp6l7YYT7phRtUu4X2l8Iv\r\n9ZSm9IFOpvooNGVC11kxa3IzgS+4kzQ8c5c=\r\n=KP+T\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID9+Tkv0CeX8hmPQTt8lCaRf5vwP3gN4E5bQlYZwsP25AiBCs6ij/qU/uNTYrYVut6W8kXsrGIlOA/yWgpbLHDDJXQ=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7044649_1645553922724_0.1806940735266962"},"_hasShrinkwrap":false},"6.0.7103694":{"name":"@metrichor/epi2me-api","version":"6.0.7103694","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"02580a5caf224d8d9a25aeb45036a8bc0c5c1ffa","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7103694","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-MpR8jgA51KwJ3wWJ34qnR5sQMeS3MJMUH8R5ExwVT7YqSKFK1d7RU7rGRGv7l0hIkmWIkfG59F3gcioEQLiPjw==","shasum":"d2194c5e042ccae698eb3f5d13fa6f5585272958","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7103694.tgz","fileCount":372,"unpackedSize":819663,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiHQtBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqW3g/+NvLGfR5ICWMdTSt6MClwUNPUZGMt2yZ46PjCT2iFqhkKnWjA\r\nBMvHdbS0qBO1Jfd9TOk1RvlqroYSYUwc9CzMZ02XM5TnloArV109w6JyqqzN\r\nicoKB/NwXMRI5lvfIGpgvvg7ceOZlwA8/5KiCAJpcQgyaDIqKn6yBhicn4p5\r\nMZe5cY3MASad5Ml3tKaesq+5XlgtRytWwtmQoHFODpKOKFunFLOVHXJ2W7Wv\r\neYNrq9F9wZlSBa6D51GAGHILFHnc7VSf8nIXpO4f+szDTw6vNMHULnAKuusF\r\nx4BW9795DU6oE9iLV956bTSS+YnazEpZp10YwjwcngDPxKhpKvQuSSq8uM3T\r\n6SUNS6IqPC0Tj0YHh14zl0pdULOBnv5mQvGCzpwtKE/kw87xpMxHRt3LMFZH\r\nUnjELdOWmodAGHgCpO1/vA3DPmBTJ9IbwaQxku6xzUpCIkDb1ap575y288ZH\r\np+QSBe5PeX+oM10FARD0Tk4LFEqiN9lGGjSGK8az/iz5Kn83bgG5PWg9ix5f\r\nz8kFBlEdEetQB9T4qiAxk9E2NCZq0DnWzF9ywKc+X9p98tH9wWbBmnwO4QZB\r\nJqVcYAVZ9bKBnGeGouk3kFFrHqiM4AuAcNrVsfXUw5wxTdhWipGmQeQFrwyx\r\nckpAa7LLLM603qBfnLqAPz8c4kGIuo5xoWw=\r\n=SXwx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDKhohSd38XGrpoEECulvWJrXRwRnK3YWBJMLg6lN10xwIgekzRNr6l2wKEu+cLu+sjy8lKnCY3xGVX4WspqYwTiHQ="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7103694_1646070593526_0.06831449074633378"},"_hasShrinkwrap":false},"6.0.7149896":{"name":"@metrichor/epi2me-api","version":"6.0.7149896","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"gitHead":"c679c7f1409fd9fdf28d0fd4bd1f8355de4e2d5b","readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7149896","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-/SBuoM8Vbc2D71L10e5CskIbo81ebiJxgdpR5qmp3tENjyR8uB+AVNR4dkt0/zgf6Hp+fagl6sAqgpgfZfweqQ==","shasum":"0f80ffa731163f75dd4f40fb27d11666a00853ab","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7149896.tgz","fileCount":372,"unpackedSize":823134,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiIgJEACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpDIRAAo3V7ktzjPVfUgMHCaD9lQ4AMHszNYEo/94FKBpxaAwi8u50M\r\nLlcvf/ea7biyj6UPYm8NPnDHBmYTL3GqWbc0HHXlSjevnCOHDSEsy5k2hZfv\r\n84FSbmB1FhXE8mPPW2hoxoxTwlhTbfIb6V7RfjOKPv97U5eNTvvs30bCeR+W\r\nq/IG+FiAieBHzey9oL++eMnlXCvOU3u4tsSU/nLWHvVrTpqW29lRNaZyIS6J\r\nA3OZ96GeAy6EoAzhbVClj2AtG5eobY4N8+YhANrTX6PtMVZR+o6y9Dza/3dS\r\nYVtHDMUfFfEmPSegjY7VgsKm38c6XjScnQ1Yjd8XA0F4gSnpjUXZMhxAMtpZ\r\nZQ4/J5mbY3p+i+5MU4YOBZvJE140uwFeONCbq97yhFEWSP5CS2PCzNzE85zr\r\n4b5quyJ6ephZ6xbZC8PyTh397FAEZiftnSOJH5N/CubZ54kvlP9XChnXSlke\r\n0IF7y+X3VU6MkexxAdnP7jE0Y/Gn6HGAch9DZmva+521cxLqWxlPIQ9Hyaeh\r\n5h99/Rc3fJsg4ANEM9z6Zeyk0RM5wdyL+Y5aQPx67FO9hDU3WpHgm6gx2jxA\r\nXAmONZucA5o/ufLq3VuPheYiDXCedyRvUa9Wh+jPTRPUU6SXI+Lz/6FdyoP8\r\nMblfuGUXLy8jlkeXk7v4F4eIGMHvRuq2vhs=\r\n=vRuw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEp6K2zs14O1Xele6wjzfnDcx9/JuU8Jrlx7yDqLrPoPAiBUXM5dRN2hzpttbbyEBFHitosrprO7Jd7YkWojurIWfw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7149896_1646395972074_0.7152888440440135"},"_hasShrinkwrap":false},"6.0.7173308":{"name":"@metrichor/epi2me-api","version":"6.0.7173308","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"c606a17b866bff28b02df312dce6d39700756311","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7173308","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-NnAsW5DFe9MCxL1JtjLtdhiyV8kL34gQWuXGjkvvznq8Zv5tI16FLSgeNDlDkeJG/RAN1UJH8ukau+PTuUKj5Q==","shasum":"f13f76ccb93df822cf5f33eaf2fdf79fd4f2cb3c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7173308.tgz","fileCount":372,"unpackedSize":824630,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiJii9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrsHg//XAuShuqfdj+MoS+YWeUAcNKCBQIAsxMuyU7rdij2S6ueerNR\r\n1euk1Cmo/as7aeWH63wzCbCWDUc20n6c9t0E9g9lG87H2HiI6AsBwrjztp03\r\nujoLb3jW5QLrufbVBQLz1B27zZi/Sn8DdVsNpPSEnmLB1W6wsaEi1tgF6Q4/\r\nmxcMeyaSbagRLevte9UPnqF/Vo4BqxEpiqkgiSZcT8lPOt7MNXcGPcGtJIJ6\r\nU60BxwNJJ5Xq/2olc099BWDb6oAOx16gWgdOHB9p7Ppc0COgmZ6LC3da8aB/\r\nPaOdHr15z8OcUZ21iBvs8P9FyYuhRk0S4a7+Q3gJl7kSkq1v1+t9jNxbS122\r\nt7YxslxYpbPA1VC5pEYABfO/Afax/qarJgaeFEmGRFCnCr3aLhw1RvR56R4R\r\nBs7Jze2221dJOasBaJHG1y1OKtVhit0B49b78znaIk0HKT0gVC/B52F7yQXb\r\n/RJCXZpPHVSzYtkOxqS9bGUwGvAui8Rs2TE8vmc+U8Wm07NHb2YKipJ6/HYr\r\nh+MEeeLby+mFNaG6+HBGQD0qiDkGepWVlI1qWwOrVLO6pafe47GkC6lfWZ13\r\nDVkrs9ACEEfwH6oPgtoEmTPpXFw78tJNbkBlLnRHw5WkJ2dUPuY+Rx61hrVD\r\nfGkpwsHvD57iatt+4VA/VClAzC5lb/laIV4=\r\n=PB0M\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCf7HPqyI4sPGtx5GV7Kyuxmgp0BUPK+0iWn+js1d/logIgIGYitYvZuYUTieVNU6QCPoiSuc69RXQvB/qx5MnL/4o="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7173308_1646667965486_0.22973816236120959"},"_hasShrinkwrap":false},"6.0.7174788":{"name":"@metrichor/epi2me-api","version":"6.0.7174788","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"1eba432b54b8ff75414ec98fadf5844f30f67b4a","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7174788","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-w971ZtgYCJrMALMxtIPhnjieGTnGV0LE4/Kd9q7IJaHCaPAAw/VFLeqLIkETcl97NmG35zZa3b9z9EtI0x3UrQ==","shasum":"af98f9b359018877857e60a458c3b380c489805f","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7174788.tgz","fileCount":372,"unpackedSize":824660,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiJisWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoQhA//V6evzHNzGA+pVhKmY44dYS9CBxCFJwDLu87HM1lvUl3ME3UK\r\nhzKAYCDk165WTSqwjQoxlRHaiiXxmW66TAnMaluxacY+TML/jt1dneS4ZKcU\r\nRAfyuPtTBh3Aza8HW8aNYhRwLiY4GbR+0gOb/EDNMwY9c9fVwg1X2OxXBeuB\r\nM8Stl+PUdylDkPKgo5ywl9k2vraJ3WfA09GgqDN5AYTGnCL/yxSKQTJ84Iuy\r\na1QxVCzVjlOryd4XfElE3xuEvb0yTMUZVZxLJu8t2StjMUJ0tx0hQIU245tY\r\ni29BznipK6qaKKpQ6sjlRrg9J5rdilZRklLgp2Zh6JgKW+2GzkwIdKissAV6\r\n/0/ilsbiG/NyLiG9rWmyngpMR36bWkgwtQzlt2htUcj0rPPzalVjgoPVLOML\r\ni6uBpl3v3jt9UksXUrGplxn+wQ1LG07UTDekG8FoWA2LJo1dvS06w3/7u4Y7\r\n1Bn/HVUPuSIjri2hB7+q0Effjw1UppzjumbZDTe93Ouvie/Z3fze0ILduzBZ\r\nL8gBpu645xsHUXDbLfOKcsH7ij16t2qij7dSJmtqqLRx4TWWM4OX3ifjcxvM\r\nS/e2vH1ezFhnN6YrYRQOHK8UOVjPiCyrjSShMRRqX9xkcCis3QD2B5EFdaze\r\nwMEgbUl7C8wj7BrDja3EgXnibNHIVVs2hHU=\r\n=e+ET\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDwUlNMrcgB72XHI9VffmUveYodEvLtqwe4ec51z3G7gwIhANOVGX3pMy0r0puzJH+xj+zVIBnZ0+gs4/Z0K+aUUP2r"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7174788_1646668566245_0.9612756031075469"},"_hasShrinkwrap":false},"6.0.7176693":{"name":"@metrichor/epi2me-api","version":"6.0.7176693","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"3300f317aaf6bf92137726abde7a6d85b273aaf8","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7176693","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-LM2slPA81r5C0g/x18L+FOeBaEerQi8afrjV4ZSE+RSf0143JYijqarb0xllahh4A9Ci4sfUMTcIxNoKUQlT9Q==","shasum":"6bf9e8ce96a388a730493e9ced51c7698a0a7515","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7176693.tgz","fileCount":372,"unpackedSize":825040,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiJksrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo8vA/+M1+RD9kOJ0moVssSAyoIiHJpmbkQIiv9j+YfOadDJPSuLYVz\r\nGqzi9NYEd4QOqnINtDk8RvMSos1gMTcO2ff0UI1Ir2nFdfqlZsNZhMh0zvAq\r\nyj/eeGFayHT8OGJn4QpmneaTnPYDpZUSY0pVjJ2UUKFo2tjDzyf9BgRcwSpy\r\nJx2r6CddPjr0fe/dSbe95/NjMNy8uw+6CxshNSZ3J+XCY9n/ptqzyyzj3yjC\r\nph+1XvjRGjwWAN5HwCbQ/DXqtUim3Dg2BzpKBw80v9li1DGGBJObjtGpfL/f\r\nR+zN48XRk854dpd+XgOocMXiktB/3zWpnDRzoX/XQgXC4s3ZrLOLbm49TdIu\r\n00AwOCO2jfoIvXFKJnrAJr5bI+dDUfOW77qO8D094AoHT2bg3oK/l/KQfqTe\r\nx+WSRfqZpBdL0I/jG9lTwEwJFh51tgvHto0KkZUD58PKMklzR8TTiH/mExIS\r\n78i3WeDCC8tYPc4X/yXtaDykTaUh7hJceQUtd7pmG0pg1kBBudUtn2EG4dEn\r\nDhoZJmNAkSHVxBx1wVluyD+5FbDbYG3OoSeQOR8WpBq6QZX4dD/FFYBBnjfd\r\nWpHlBOQoVBSuoPFXqT/stgIRud4vIG4el/0ZT1zzkllwY5MUJLTzpMif/aay\r\njuVQ8UHz03Jg2ZQk7mcXEJIkuseLxME9W7M=\r\n=Jh67\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCK9rZSo9SFOeA9hDXmW7024vGy0LFdvndxQGt1KsjD2QIhAISvXrEJLBZrwCjHbEvodO4BEP4IguCx5XRwoA7l3lB9"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7176693_1646676779679_0.24909285262677905"},"_hasShrinkwrap":false},"6.0.7183600":{"name":"@metrichor/epi2me-api","version":"6.0.7183600","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"a86a7bab57984e9883d69822816474be136ad6ae","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7183600","_nodeVersion":"16.14.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-JwfpmqaZgs7ymjVqAJbsl36DPQAu5Jlj6CSzLrRWoaM7n3XvYldUyNLIA1JrAOZRXKa0/raqftl16nQ55H8YVg==","shasum":"14e73293f9b2a75cb49952bdc6c7ccb2e7fe94e6","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7183600.tgz","fileCount":372,"unpackedSize":825040,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiJ0cHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqw6A//WWN0w92yaJBGLpT8S9vFgkdEZV9VmEbsybmv9FQIT0j4DN2w\r\nDD/iuGfo8YPzZ4SfZeuDndJCa/tg/yPealw7Vbk/YliKHdP8xz4bcpwAezxn\r\nK38NfFeoYUqxYelT/m9ze0w3E6ycCemEq8oIFQleNssc69njKql8E3aGlBjf\r\nZ54HH2LYPJ8tIeh1tcn4CbHRUDoOmujzlYlAo7n2uyTj3ESUPwOEamdfmahn\r\nf6L+Ym1oHbWH0taFWHbhVzUnkIjruNbcbr0InRejh5ZZKxv7AAwCJSuZMt6w\r\nY5XhAR9PfAj76RZPOLR+OHEWx+PKes68gmpEck59vKfDOzRHJyJj4fpfT3AF\r\nUniG6Lts6ERh/T0dJGsWxRqcKIoVeA2f4T9EQ7tF7Tm3p+droeB5x+n5M8ex\r\nvIfHk4kdj+x0XI0D3sp+7s6FXXddfCbL4XNNmEOIjIA1vPu0r1LIPLchroTg\r\nFNa31AKVNllVEzgcbqIo511wAuGYdnnh27eSOii8S1x3zoD9sbp++uObrnS1\r\n8r08qto8lIAT6b7iOmQ4muFC+GLrElUponfo9YtWkkbz2tvLbo/DO06sJoZ2\r\n1rBBSzbslwsqccW6Bu+NkKboCC7QOZMUXd2ZAR/DLfjJlk8IMtK6DZOvtta0\r\nK/CNRDLqPfIluEpmkHLbgFDL1N5rQPWmrJg=\r\n=mjxd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBU3aLIv/OUou56/Ii/wyk8Fwn6jRke5ofMHhk/JnpH6AiEAtco4G3sqHlmJsSwbFhrVCQnbnIz4wYylfWvbeabYMyM="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7183600_1646741255442_0.6532317424875105"},"_hasShrinkwrap":false},"6.0.7292964":{"name":"@metrichor/epi2me-api","version":"6.0.7292964","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.5.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"6038016d018bb6ba6de8492cd94337c94e2a8700","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7292964","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-y53CfaLZf4dkFttug40G5aRbfoQXGgPwDAYntLQJ2pTehzbO+SP52GXFrNlZPoYQIiW/bRSPfPVvFgIw5BQbJw==","shasum":"42a21de78497894838c492d7a4ffe85660a6dad8","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7292964.tgz","fileCount":301,"unpackedSize":584139,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiNGIFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoqlQ/+IH3gebDfxhrdqJgP15VqCnYFSXzeHTjHgzgAH2ZdI2EYut/R\r\npD9Qxz5FcV4JHUGcdLUY85QvoJjny8edKm2HR6RM3NHjozhg37a4XmhQ3tFl\r\nzCbVhQRS9eXk0HZMaX8rlN+ZQe6C4aO+seUuDNeIOaVGyUu4teRg3msMT5D6\r\n7WW+eudOOYjIcAWzGxvtqd6TD8HFyPkNJ7jIzcJXZSRm7Kjd2I7TEXvhkLGZ\r\n4CUHcybfUH8TkIX2fgNgc49itwWvxvMxOAOrC3we0XWK4BdTx4nUa4NC4n7z\r\nC+3Cytp3IPPXOYCoQzwDUlYpwyDlFR+R3W8P2RSNEKwElcBDjGmBu+8oAlEO\r\nxmviYUbgZH75OIp2nsfYTOChtv7oCWyb3PZuu/WkRsBaxZ8AK4bpIsUfaa1G\r\n2w6tI8ppjYy19lBqOXp2xTWAwyrcZVbErdmqfxblEi5R0PhB5ORl6McgHa05\r\nl/LGNa3e6W21lu7fpkk20QM6LmXI8POSyNxYm81igRIXmQAND13/J7oZY8R1\r\ns8fQr0Hh4nst06SbNYNyMSfp4eUXPihyXWgrGKSA41hcIY9clQgQM+L4rJTy\r\nTsLzVx7dtGPcA5PF/SBTcGtKgmCOge5qvlEoQCBIcB3PlucI0LMl95lFr7R+\r\nvWHbLAfgl/awVEnA9GB5bBWerrpSRQVEDmY=\r\n=3XR8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAcZua0K104NvEZbubUaL5bu5xtfgD3Dse9bez+ZqRDBAiEA/IP654JDJAngtIhwOgMCfuKj1VOe6g3KLUlgLlIiBns="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7292964_1647600133413_0.692958921333751"},"_hasShrinkwrap":false},"6.0.7298596":{"name":"@metrichor/epi2me-api","version":"6.0.7298596","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.5.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"2aaa11e509f09405d438c537dfb74c5c873033d5","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7298596","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-M54jIjtAe2OIT4OPydanisj/MV+7+7id0u5X7xdu5t9N4u5CEUtcrhPqzKbO0khBByPBQxO9DVAbA6qAOT5TsA==","shasum":"596c324a4fe40f689fce94bfa86e5709e52c6b80","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7298596.tgz","fileCount":309,"unpackedSize":589451,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiNLRQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoHhBAAkXgiScD/7cZjLApjylTkxAdF1mlsNwC1NLhvHEpTO4rljsT/\r\nNIDL9Ixncc3u4OQCWLsFEilZm0DbfHUReVqvSnfI0dy9xl9FMzd/zIZe35Xo\r\nJm9glVuhIjFdaYJDfcVPUjCrHQ+hEf+rkFyrKN0Ndiq3xor0iCMPvamqzy+F\r\nbtf6BgTX1oPXYj9jdHWPKY8HcWM9v6gHN9E1DxdSmLWYhc4Nq5zLQpL3nWme\r\nztwWRuKxxTmfnWuLyrOsbKuIxxVrtdsUBV0u8JTK/8xqYdhFLFox/MtB3x/A\r\nqFH35bOfY5rTz6HfaU1c4+xFhMyNYK9jnLTSehsgIz5Kx5NR7yEK47jp6OAr\r\npg54o2/Iky+nuCAHJenP0z6eLEOcqjZwLsa7YSCKK8MQMqUCJgM6YHp1QLyF\r\nourJFub3GiJbWWe5no7lP9YHoiKeP7vJNoXFELvL2SIRd7OUwNWiUgohv688\r\nQwinyk0v1/KNDtFcAo7ItZS8FTuXVtcnIG4KCmXMRFn5N5GGler/TVbXv61r\r\nNlYbaWDw0Y2v6Fmd1ZyP8/c0J/Rx6PflnbB6D265T0hT6tbNr36hh3mD39om\r\nObIt31rldKwCto/T0gkeLHykE6A22wkmNUGDRPWFxpLlu7107El/iVK1R9CD\r\nnUlX/UhFcnyl6nRwJVBUpDf2Y3KDwFT+D6M=\r\n=wM1C\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAalnr6UznU/lrLoUPo2NKMQnZibi9lrcu84HLDAWk2pAiBlTqt+NK4zyQh1yE9WOpz4XbHqLE9FtSwOf+tp+EprTw=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7298596_1647621200840_0.742798045923543"},"_hasShrinkwrap":false},"6.0.7299067":{"name":"@metrichor/epi2me-api","version":"6.0.7299067","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.5.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"dca74ed05b8405e870986ee39b8d6d89fa5bcee3","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7299067","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-KsjY+8IoAS6XADXbGz2mADlPDiJ0yopvY5EqsbYM9U/1yP+GdlpSTkSwTpqvj4gOxWr9SS3cjv8+hgYmel/xdg==","shasum":"fb389ff4490967d89e02991cbe8694ade558a462","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7299067.tgz","fileCount":309,"unpackedSize":589383,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiNLuLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmovvw//ciEZ4lfSTjuWOM1hO6pyE+wKtJjYm0KaW+ZcU8xo2aaxAoA4\r\niSfq5YR4DtP7ISv4pQDLEBDg/ls+G3bODL2tUkb5RpmBvVdrSrm7xfU+CAbt\r\n67W0xvvqwCIgJ+wqh/z6iHXbpjGgqW2wW5tYochgYJCdaUow89Eem9lRMEcQ\r\noFORIy5YqmOKfWNsUBnMVQkjAuqgzoqBRBQpf1WochsA/jNX7ih30vq6SRQY\r\nAIsTU0gCK8pkGxeZKZ78yacxAiiTDh409AnoUi/DQ2ZM5MFzQc/d/oVh8Db+\r\nXeAftft4QH8IJM9ZD/6WY20uxcdRJ7NLtwYlYWQMJDJALMMc5ALvunKMp5zr\r\nwF7vRUNsT4mPOhn8yl/lUELmzw32bYO2tJ/hTfV1xcCgI0Zq83U7s2IVUkHJ\r\npIXH9G/zNUqBixmaqHj8Iy84cJ1nla844K+YOJSo9/0Dv3/NltguM9lUyhfu\r\nfY7yiGmH27NMC2OFpRItUeKk5UbKGK1iXgapoDvfkQMD9q7OKcw3jRvynS0Q\r\nPyGbPVqNIi/t8F6vQzWUBzKqmki/H44IjcrJ7Wj7Bg2QLKo7dWDCDH7FG1zv\r\n895k/fBUo0MF+M7Se765+H1fapAOJiWZ9NZ1sMaOxehWro7Irl8BNI+Qc4wx\r\nlBb79oVpxSM2uSjhye19iws/rD2IsWg8h8U=\r\n=gon0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCgTHj6bUrtZctQiTLD5HIW60SaGoIIK8kjKFIv7/tsjAIgD3W9sVFrdBpMII7fNe8E6JYZAP0zd4pyCFf1tfzPnxU="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7299067_1647623051680_0.1844773211986881"},"_hasShrinkwrap":false},"6.0.7339081":{"name":"@metrichor/epi2me-api","version":"6.0.7339081","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.5.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"9a9b1603a01576d9c3ae671f1e4354dbfa67adfc","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7339081","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-u9kZ9C9uz2q2k4vk3UsWF+cFcCe4MawaAljzVC1MXNxMiKweCFVP9hOv4LV2ZCUhVLd20DBztu87Ahwcw89yzA==","shasum":"077c9e113e0340bb1a02feb86e3aafdad22c9898","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7339081.tgz","fileCount":309,"unpackedSize":590393,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiOuyLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpb9RAAmsyxjNjaMSyBtwNBUqaKK30LzYQEtg2fe8xMdSmfpnizWkDc\r\ntP+wYDC02Lib7OMR5CIcKBp4NIcotrMXK0JnsCd0TpYjgepaSzsvZCMG0Z6l\r\nQU7hRv8YnFuG8vMrdrfoCE3OCeYVhuMMUyI8vxyooKYxbxaoPbvd5tfjNeFU\r\nBaVIPCAtasiGlA2TRefNrBe2jw32N6liC8YxKQYApvLiIrHBNcGLKGoWKjo5\r\nQXOJGHxDwMgud2/iFc8x9/U7xpbMy1Ra25Tb1dacexZTbyRyQjFJCWFkoc32\r\nC8mSpI2jxxNAkg8Ixp3NMbxv08bOojY9oF/DFqmoboAQ3Olm2o40obsi+ZmW\r\nfYIcNaO8D+eyBnDfTesTKnHRAILPfRwAlTUAQzMnDC73W69waYX7XnysjKsp\r\nBDxYF0MSIAaul9Hfv2bULTh8UJJBY6ufOjP2ppawbypAJ2tpbvAXbCzlrJ4V\r\nblmXw+zvVKccyp3Ue+P0PRFdduoXT19fmTIWxj8J30upbrMNuVulcNoxk8m0\r\nSQ+LxtkAAezIM3+3w6Lc22snHFSMIgE2ORMbnvZxYrFPUYl8j0LiNNwn5FED\r\nXmCh7l0diuRgGr8EY1HRBuCc3Tl/Eo3mMNbvu/6JuU+UVgGLSt9BvO/RMQLw\r\ndWx3M8t7gY8CdWFlTOEb1i39xao7/dd+aJU=\r\n=gO3H\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCJXR2UqwN1ok09pMMYc+LeuynI2sL422oUyfh4+NVwLgIhAMO865x20b4Fm55Gk6Lzhm4SLCGKqf7fiCu/Ed1xTtPx"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7339081_1648028811052_0.10929760046313297"},"_hasShrinkwrap":false},"6.0.7346771":{"name":"@metrichor/epi2me-api","version":"6.0.7346771","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.5.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"5650dee188d249abfa17b26d5e48b6a079c1c3f5","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7346771","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-7Whc3Y3/gRdVA5yTdvLwN2vuu+amM4+Oqd+6wZo4rD2wy4cC1YrM9H/Rda1lb8Y4lQjNeXJNpvThgJy2YX3ndQ==","shasum":"6ceab0268db1e99d2daaaf16da8c9a8dcbbb1c2c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7346771.tgz","fileCount":311,"unpackedSize":581703,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiO2TDACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr2Sw/+JQlc7rnF67XYNAxWXznDVHvuN4DnWLQ/49F8w9zZdPOIZVr1\r\n8w5z+LSjXeiLkU2OxN/5H7H+1BWnRJepXLUQ88hY5K1CDlUliBZII+9Q/3H/\r\nPODxXsHdNKlVH9ykD1xsYEUd5tSvRVZUr+e/kNM7VCo/LIv4afXlxYhWVQmK\r\npYmGOkaVkkf5qzYgbfkeUTE08ltb1ryXMOiLLtTmyY8yF9RGrKXQrUHBB3kK\r\nPs9wyxsdkObxPy4QvpcUouHMjCy7rkvjcMgGBsLyBg1cfHAD1vm4LyoWiqbB\r\n9xtOldzwtgmgsvrUGOxNo0vaSXaCgzRUHoprbZoPM8zoKbv8bNUu1Lq7C3x5\r\nTyCUaWQNzZFep4X4qAp+KCG/ig5feNf4oYhAeSsQfycHPEr4NZ0Jvf9oqrDv\r\ns0ON0O3JJohJHrUiVUT+z0uoIqHtW52Fh4hFwxHc8/xmf56fkGtjVjAK8ugt\r\nYai0wBYdKqzeWans7d+2CvhXgN0PKluW+KCwqoCyyvQTfhwWTda3cR/VVAwr\r\nL/Jv299YpMRq1MVndqTgxuKDtiPaUIsSLwW91az/EI0eMkszFh0wXnaegTvI\r\nrxWC5iBQuz5EVfehBXZfOIkbYn4F+KSmqHXJBt4HRejlBb9CNXDcnKPTZx45\r\nlCssx+kdXS07SLAl8eBche7kG/2uHhWjRBI=\r\n=UszI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDVltzbGNIt/ziHxJwF0/TJ+kmPWbKH6UkpZT+I0VpUYQIhAP+/T/+XLW7lz2ehd5yDSTTdmgkiQhIjoBIV82RZm3V+"}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7346771_1648059587764_0.5671274771485972"},"_hasShrinkwrap":false},"6.0.7346926":{"name":"@metrichor/epi2me-api","version":"6.0.7346926","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.4","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.5.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"19f9ca928c9c31e24a3395b4e7a987ebd976f39e","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7346926","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-j4DbGIIVm6JcXQIrQd8X2GIK3fn9xROw3/ebhJleRmpfhC6sJkKkWU6JRhexGRup8exy3JkAl8IFyDwV2rgAeA==","shasum":"ba15ca8c666efc455e3398d1ae80405ba10ba46c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7346926.tgz","fileCount":311,"unpackedSize":581897,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiPEG2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrRzA//dJCqDIicJ9CVvebQNJKF3gN0RQxuwuQ3vr3UW43lwPXbdvM5\r\nTzKk5T3vHe/61SWqAtiMwr+AdrIllBQjG2DF0sJendU9ihLm8u476qbndWa3\r\nE2lU20e20diGOLypqzlKQFvqId8+ocf6//vi0YUgHygPss+4NGF7o+AtqZJ/\r\nQQHS7Fn0OfHS/428cjzkuh4Cv7hQ1JzlHALSdb4+g4zpfEcB9T3GchALS8zK\r\naDghiCGTdzIYQnCfj0JfURzLh3HXHXhSs6lPYbKn6W6MXhQfvCTEogrV9hKr\r\nn5jUAP6fq/bGpNh+22MoL4cWXipHESPEM4DEsNI1ZGHTShFJN1fcmQsG5sLX\r\nrL1z9/7ox+eoCpLv6sjP4/gfV29SSR0ySCpAjooVnxUCF47RSASvNwn/M3qJ\r\n5YC5BjebcQ2e4dmrdDghGzni8eEj/KQGJOe911RLM9Vm0I9gTk86JfCS0Oi2\r\npfpY2f3HUsr8OHIu/TMHfj7HkEmcSV4sKtHqZarISHl4LM6Ne0t2EnTu7g5Q\r\n0KLMUUjZ4hKyXTzWx3AxrDsVEUjwi2+OWw5BOwOZ74GyhaTSEGSovbaOcYCx\r\nI34IacTMtl+R2YlguZnamoFsEceaIKGYRFwbTwHHJ2VzBUbCc+2UaunaFBnR\r\nvocEe6NNkzJB5pU/BXYyVAaS8tEmGfCg8VI=\r\n=QHOw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDbk1bcYkVuiXX9IQIKdmsd7cYbg+3b+1txB0moC/zqCwIgYiNBvuik1sFDkzujCSL1at7lqKDxmBEJLh6CnnRMWmk="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7346926_1648116150222_0.8723309777518575"},"_hasShrinkwrap":false},"6.0.7408877":{"name":"@metrichor/epi2me-api","version":"6.0.7408877","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.5.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"25c15b4bb61c788e9dae89eeabf9871ca2df4097","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7408877","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-HEiv8R84LpvxRNkGud9P2E8HioSar54jev+dHCPK0DMiocWCc6DyCJQ3UjWxYyOLYcK+dwmoiOJ+6ODjotfQTQ==","shasum":"9b095094ae8b3d23b143509060e766180746f564","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7408877.tgz","fileCount":311,"unpackedSize":581718,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiQzMPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqFLQ/+PmaiUIi1khvF6uxTFPb1O/OYNZLdZC5+rgVQO6OX2/0WYZ0k\r\nkqT9wHk0BXK+kZzBGTiHEtGoHwMeYyvBj5TH2O1i/MN2rWTVOaydCoQwB5mk\r\ndOR5Kro9sJsX2zGXbeVb6qmZHDJvFBjzS7IwoiLM+ZcafjvEBeUmqTQDFCqV\r\ncnMUM+GfGjiPWKBa6NnRJwE7RXNiSoGoSVjVQS8ayzYlPP7ld5gaTGQCyOCN\r\nbj7MelZWQuQ+LMCCX5AFRJApU8lkSfexUJzl0qcXbRcRNomOcnO7tTUzjdTC\r\nucQSh6hLjvOxtmmVi66MrP7ubTtVdEGCRTHQOmlhhHjdZppfI4rVZisMmmeG\r\nbuRFWkRUU7Ogbk2C9jkXTFX9x/uap+beEFKqkf0CQzQ8UK7SUNuAh6l8drso\r\nlABfOq4qo/XHOfAKm1aVBuiTPON3pjmI390JPzpmFHydpbbZ7dFfVV+YHAR1\r\njBWww+2CyYe2rlVKDVf3y5C6O2Et/NFifn/4j1UGZW6tIYQ1N/0IOTYkKdzy\r\n4ZPTKCusaBo0+u+DDHp9vSqbFzf+flJuyfsbubPjQCGJ805xU5eKwQfuvFg9\r\nDxWwZX4zpN0n6l9/zHGTve5y2bkO3/gcvov5SsZBcn8KPo0q4oIQgZGFHs+6\r\ncAFZwgwG1MKbE/xTqQ+IWkDPKelnolLszKU=\r\n=6OzA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGXT4I33Dj7FQMolzNj6vpl1VIBl0eCKa4RwosMYHXDSAiBiKFes/NlmYZkXLHiRYhijfJhJiOC2D/TLAHLCVOFiHA=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7408877_1648571151654_0.4937688548961954"},"_hasShrinkwrap":false},"6.0.7476504":{"name":"@metrichor/epi2me-api","version":"6.0.7476504","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"31c3c6e60756ac95e12e3c7e26d1fe479045fa4f","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7476504","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-EPuQJP3zj3wEc6NahwY77TvoAJZXAesblBk9x/FRS0cUgewlv5pkuejVeJO8y4oGZZsVPlBnCcrjV7FVyT/hcg==","shasum":"d7d737d6bb5adf8068e486808ca7f77c5c8037a9","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7476504.tgz","fileCount":372,"unpackedSize":825039,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICzilxp9aDu98ulER0hs94A0AqtlVidMpopLoKvdUTbDAiBPgxNY83icRKJ7ZfhVX7tqIXbNFzu0ICVpgmUJjCekTA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTBEjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpazw//Wa8uRaAgi9heGY+uubPSkucccGkbNaFwEyj2AuSRobo36ObU\r\nUUKLIoGedt9DTb+A/wVVSq4ZhXlxFWxKKjTR0R+3T2I/9DtNMUKmE67aB11x\r\nAT1svjjH3qh3qTTElZ8swHILXNJJcvtHfiAcbZQF+/0hwPmAVJTE5n4G0hhj\r\nNtTnfirpPjFUSN3e/EDcYXN9lkPltcsW7PMzjQUIGqg9DGpGW78Sd5JVBapD\r\ndrnGvZ8LVcA9h7DzBrhEDPRYugqsWpHDzQIEWCxyecbikwAWzJffWKIjYvih\r\nVR1Erlutl4XsocLW81scUeXT+stLefP4uRQVIVkPzj52qUiwejrYBPg1FkA/\r\n/kb8FCWXWUTKITbrn8WZXI+dUq4AN/SHwZ7HB7aUs/GTIfMx24aKrquyE9qI\r\n22cuVaW5Oov/lEZ1rTjb3cMqHP87+2LW665YWg23FOT5xvyC7kxzxfSMmVDI\r\nNNKUYHtKr+JmtPFf/HNn5FBcZBfETxd0h7lhsk58tAcZTm23zuYe3sq2YczG\r\n93yh4tz02In9r9VjL3xf1QdjSDIguRPs8/IGeQlyeE1sRhwNA2t4MXXRoY6D\r\nd+6EXdhobMPrUoT/5IITDRNdl+24go7BuBrro+hIomOW9oUF2AFPT7YYNbMW\r\njVOPeZ0ENgB+Ah2lmZX3SnqsXfRypDYNU0Q=\r\n=0JPh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7476504_1649152291075_0.634737615603757"},"_hasShrinkwrap":false},"6.0.7479716":{"name":"@metrichor/epi2me-api","version":"6.0.7479716","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"a306b9f2510e5c26e4d6b522c56e6c24594021b7","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7479716","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-RUZ4VgrnakBnYpz34ThCyBB6dGFrgsR+dQLiIlFMXqFxzCJKx0ZmWj0HPtJB3twpuNIOdsbXzP521jwz2Q81XA==","shasum":"e84b5816a676f64bfd73d49e6bcc2ee4dc532a5c","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7479716.tgz","fileCount":311,"unpackedSize":581303,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHihxCbfC3IcICB72A8L0ZZDhBQRFqTpU+twwyY+ZEeSAiA5evFc1YQODEQ6CDu8hvJ3GLeDJs8VKIc84l2RYHhSxA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTEgHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqfaw/8DA3TQ3l4BWvhgjXgzuow165T4uE1pfB2/Ma4iaKd16xf0CXt\r\nohiA6q/JMB/c18wFGX9KOhUaz9gBFjEUv08had/CQ0iJyfWyUFw0IyDJyykB\r\no8iaM1ngFkmVB0HaPLARqOuj+hL5N0QHDXlIjCcmu7gcgmcjvdymgUc3L/Ay\r\nC5L1vnhky1zjgHLSlH9nfLlZIvd5h2rjt/gPURGz9D1M/V32c4FA93Fr2hjV\r\noCtnxCaaSZm7ukHflat5a12WnaxuQc9k+TB5NGdpnvVxkqFV3Ntq2+E7XF/C\r\nTek2Kwglz4tjgsfwijmnMRaG7DbLROI2GTc87JZGcQb82tYq5eWQPRRP374G\r\nH6VTLt3dGewcaR5+OSMOsZmc8rDAgiKoz2SV+6WHy2B+bWK2+nH19o5+wJGE\r\nzv3iEt9VyHJIiW/YrwcVFupQ7Pu9lY6vsLO1AnxN6+beO3R6M81//2VPQCxq\r\nPwAMDqn3vYq7U3WQTLgbUfF/OkHm6enG7OmsJJzfXfV6GkMmdf+PXDa8Hpbe\r\n8EHXjjnQCV8/CdZkB6Vt2h8I0F/6fVeImdaB4GiOlfLSq3J03dsSf78TLNTX\r\n59B+aqTO4c0eLFRzx4+Qyf62wxR/SbwkzTrPvNSIcnRD4xSPvYtJls3BOt6c\r\n1WoDSlDABNxQTQGqmvuNXjAogzSX4l47At0=\r\n=kfQl\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7479716_1649166343523_0.999579512388173"},"_hasShrinkwrap":false},"6.0.7581324":{"name":"@metrichor/epi2me-api","version":"6.0.7581324","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"30d3fa43941c262488673ef2aa30673ec28d469a","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7581324","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-4QxqLbl9skcrKLhJZINLvADGKgN6tvfijqp2EkbmDz7KmAyDfAaHoBOaWivV0+1Wnqwl25Z+XKC96O/gmhDbtw==","shasum":"e031d7e450d3f69b73cee0d8e1cdcedc3a3ee5da","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7581324.tgz","fileCount":311,"unpackedSize":582218,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIETKvAFBYIlmJEdJgkI5/H/G9z2zsneMTOiViJWLNJpmAiEAllhzGrMvwTbnc1ky2ZhPrsv1lbbzmOaIB9+DxnxHfc4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiXoN0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr58g/+I1NXT5rsvgzEmK9fZcI1YZV8Om1GLmPIk1/YZ1jV4kPTHkj0\r\nsVu95aPtHK2B8ajAyme4L8G0Lwb4MWaHKiHeRZrYsRCJGNiBCj16c2K68Ge9\r\nnnPS7SzfV6etyPTAJsxk9rTINhyNrXpVi8Nc+79bQHpGimNwK2sHS1zudoW8\r\nIOIFRrp5fGgLtcj9F81qdeegf8H+OUTzewEPX2SYCFJUixAe6LCKhMtpsUuB\r\nuNYa/o1UoZ6T6VRyXoDL2WO4N8GM+50MgUXeaALEN5lKzmv7rlijAYH3vj+W\r\n92sY+iVZDebW4uWKTyf/YWZfOESI/qsFJkq4OibQ1ho2SNbEh9+yOT/HLKBt\r\n1daJd+roiywwEgez+tfBTc7dQ8cEhWDGh75Nn5GukQRylvZHolGqMGglz3eA\r\nLjw8btIlI885l/v+n5mkI9mFZrWe/WHQWCsj7FmB7qNS4A8jSlqKCzpMAx9Y\r\nvHuuTDH+ltKwP+34/UeufZGvRyIKWM4ZxuhxZl32mzK/GQtBKZkfRqfR2mfN\r\nuXNmGkNR9qHmWtN/dtY/HAidFs4w0MTxuw/swYjFr19WQJeJOjncE3RVoVgR\r\ne/ogvEWcRQLKQE0aqo88E8osD/NephIiWtfDEgQObMT7LxgSRdgGl3wOL84I\r\nnZyiIUl4GRlQqXWYwZvXcPgQSF86IWbBRsU=\r\n=Csnd\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7581324_1650361204211_0.8446971192474724"},"_hasShrinkwrap":false},"6.0.7611483":{"name":"@metrichor/epi2me-api","version":"6.0.7611483","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n","readmeFilename":"README.md","gitHead":"3703f2cb3cf3cea12e0cd602d5b3dd0809e90cca","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.0.7611483","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-uqdPY/9L9CYe6Muo23hkReFhacKFDC37LME7P1zJYL84eofX7Pz3vPVeqcm6A89O0Yr/ieLB6ofk0T3Jr9ikhg==","shasum":"5f8b7d574ad6c037a0c04374e50351ec4ad24b71","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.0.7611483.tgz","fileCount":311,"unpackedSize":582218,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID9eZaGe5jcvuELalh+sZF5akfcB24h8al+UZv3LnqhlAiEAg8d4pWsUJuxSrwbA/H6k8vASaJzVIDUWsKNcuWx0WFE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiXoXzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrnJw/+Li2o3HPgONTLRxaLgNSAZEifFsPEi+/UEZOAI3658R8t1pO9\r\n4mfXrb1q7Ya7OBcUwOLoJySQDec/pla3AL3g5EFhEWHCkbv61i/KgifZeqGD\r\nCDrSgOdLnaYqZIWNLRMAnPlfe50SpB7Kc56lnI4n5/3gv45ZHspeujw+Z+rx\r\ntVh6yO8lMqHFvQZ12zXqKfO7DwzuT8JDKDL68wbOd81hWSFYtkIDPldrj/m3\r\nof5hFqQbY9XG5T4LzRiDtm/p7rHynpxV9VCxLiNdkyxGuDgNJqJQSoEqpYsE\r\njUydi+hMQObMTXaBFjeacBtD3gK/25IoTG2vWU2CHQPXi1oFJHaV6UZsYb/b\r\nOyg89iRQ1xlHyKqejyu7Iw2qaHLGcXj7O3HGMulHQcDZt4BhJ7KpE/KWl9L3\r\nAGZcUGs0i1Lp6VSOgRgufzFgo+XLpq0TpxDR0XOvlLvd/GllbV6EnT01kGcd\r\nb3i5EG0DwRcMOkcYUrk5Iu/YqE31TCp7QCzth/6rdr27mKZzDCUmaIx7s0Kz\r\nUWVbdkoZqrAImsUTYHJpwQVOeLaU9El5n4/TlWxMF9cWY6zzpqGNBNvTm628\r\nYQv2yhhM9LeSKCo7uiLO8PDOGA5uMpkDce8nVfXb2QkTPrh88WTBpC+oBVUX\r\nLjtUM/V8Juxs9frWo93QITAsJaFRj/yYP3c=\r\n=nV1q\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.0.7611483_1650361842814_0.7161694041851587"},"_hasShrinkwrap":false},"6.1.7810599":{"name":"@metrichor/epi2me-api","version":"6.1.7810599","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"02dfa76842d795f9ab08df4344489d9bfcec915c","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.1.7810599","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-ISjCu2xZOiF42GWLREzvlFgpYkghtqTazgRnzDF2mBdPiz1prH2QvGIR5TDidL6ClRXcS2qwiUoVHYgHkAr/8g==","shasum":"6c84347337f38b8122735718d399c58ba3915ba7","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.1.7810599.tgz","fileCount":372,"unpackedSize":820099,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDFAq+M2HVBrrQGezvD4yrILNfeujj/+YwsoHy8v5+jfgIhAKLJjFvA/OgjpbmlGbACncCl7j+apxC/XblItEU9thIS"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJieU5zACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmphJhAAkLidMETC1PwznOKcBxyr0KsR8aMEq0EDwjUCdOeZX6nsKodZ\r\nmSnJbrgBI3foThnCckMhyeJAvwTYY8MmXA+Z9yju0ihYMqPUe4tkFkoWBr3m\r\nukJxzmdINk41AAN7PAYB0Bn1ejAAKHX7h/gpAMjj9k2YaXs2eb7nJ0Fildul\r\n2IGxcTeLJTiM1Zc6rSQxzaERAi2p4PwIXt31rKQybKTkV+yai8pV0OAz4VlE\r\nS7h1oERilrmVeLMbzgM0W7nCyBZs73xLp6N52hiX9AIcldWlk+A5sj0WdiDS\r\nWQPqSUBaGV8yGkkwYiUI6VVYdWfogOLm07drZ9FELaUUHBYUpZQi45KIb5X8\r\n34Nv3YA3UemqOFJ8KdEuM6LT/vRE5lINCSg2+EDCnCNdcwLF5UbdDZUK1cm0\r\nYZC/xZC5zBLrE6vqLkeQrAn+z9BfkUiGRaqApczrRHHXjOYRfJzJqKr67VG7\r\niKmalvaZsV8jn+0UOwIBRTBDUgxIbJk3XEA9+ApHE+WnsH/koEYmUeeqCRRh\r\nJnfemGvFBssfSNUHSkNVb+7T1z49pbIGNrqoOduE59LWsZHAmsSPNeDwxjUb\r\nSyoC0IqBoPRe1ggHi0C0ER4TH4/HiryIdqKwGb/9d1zTJSOg36h507A5xS8m\r\nTQF5J+3vTyaj1Tyxd9hvoIvGLYcsO2SxRZ0=\r\n=L/uj\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.1.7810599_1652117106933_0.18970092782457493"},"_hasShrinkwrap":false},"6.1.7810647":{"name":"@metrichor/epi2me-api","version":"6.1.7810647","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"14b6f70b4686eb11a10293f98e2dc3505b854161","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.1.7810647","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-EtMSdKzPELCJuZajRNY3MSkO3r/gj08QwlSuctoVQgXOJ4VTJNImxipHpQTqhleCOhBhs1niIlGKg0YaICG8LQ==","shasum":"85932b7647606c22895b1394cb952148d5498e18","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.1.7810647.tgz","fileCount":372,"unpackedSize":820099,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDep1AQOPruAQV3vR9HSFjhIGNBuT5mt5Fyj4xFwHrssQIgHguKxT9LU+4M+QpVaLh5se1kBe6j4xX1xOoJt2oHoTI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJieVDFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpp+BAAlPEZRsdrKWWojRkMLKU39RphIePc6ShFadJhi2/dXbBZ5jg7\r\n/N4jrIOHUiFbRMPYPW1ulTnsJnmWkrYHUALSbfpGeoYtoLgS+40n8s9cu99A\r\nk93uTS7l0AMAt+RcQaQ5BHxbHMg1/PIebC349Hmh5QJIJCnnf4IAc7M9G9/k\r\nFuAgtz3S4DwM3tUn6AEcAnthdz0dhNsQFRrIybWtHlW2/4PtfJ4LrdfUx3FL\r\nSAeQWD3sTX2NdKPcFNGQKjnM6cRdR8I8lHeWkcuRLZmCU1l+WjgEPI5MD2/q\r\nvuYLi/ovIJDFesNDky9m1daoheQFRJP9+i2jnUnjSDzzeKjAaWWa8saweTw3\r\nKB63TcuXAHD1pTvaMpj6mhbjWy6YS5FP1h6paRh72sajjAtRW8j1ReVwJEEI\r\nxwb8teRhXGTN+Iv3jQ6C2s3GjVEtKVe8MIM7ZTE/7jtDkOLX1LAg2jICLp4U\r\nY97rlDXgM3kbRM1EuZ+Fze2qW7TrmzommlFZYk5WUNwdDLP8LJ7ISZ5E+a1N\r\nyMvoywqM+GLenCwSmvIfMQ7B261Ul3PUUsRr1/Hh8CA/dwZdNDMJ4Zzcjmh0\r\n8qH9ietTx9KTzK8Ap3hGRyykKNnWG/DAYOov1NZbdwHEWnzHL7Ddc8Jevcxe\r\n/boi5XRjdegWmoIeKkvyaVO5+VXE3fpyHRI=\r\n=9ncy\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.1.7810647_1652117701525_0.6754668039127385"},"_hasShrinkwrap":false},"7.0.7811028":{"name":"@metrichor/epi2me-api","version":"7.0.7811028","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"337fd515ee0d8745a6680c54fa52cddeadc08143","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.0.7811028","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-CuQ0GTiB+QF0CQJYKua6CfJG6V2jN61xOXBDGUpUZK18Y7M7fUz64y7hMceUwZfMgLCn2PqtDQ9YJf7z5UQ5kA==","shasum":"acf09681911ac76f09073d8a3ae20af6bfd676f2","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.0.7811028.tgz","fileCount":311,"unpackedSize":582672,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGH0LrUsNLsA754pzCf7/2k0k7/FA9HXbkQucitDCJ9GAiBE0vrrD4sH3MW48ub/2nCtGA5gaoQe6x/uddOeojX4pw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJieVyaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqVTxAAnVkmjQjaUiMDwttOTZi4O+Np+K6a8yCcLQRc09/CQ/SV02de\r\ncCTPU0b/m6nsLLwaUZosZaEK2uqpBx5hN8v60NNituD0UPEqZZLG6K/iHTci\r\ndYo07sUiiWgvBW9zLWnAHz8ds+070iMslv0ePpuiYgpHT4U5PEQVMSTFur7h\r\n+IIrp9/+SDjeJD+/OGa+nJ7rwNp8ZT/lxIAUWmmwQilSOHDH8YyQ0/ecQgHJ\r\n2MyIIz02czror76SGc13/nPFOAlaG3T0NBjT5r9KOSwjYrFyvPGQaGVj6mrz\r\nJsmqxAHUHw2qBwgwEahfb//efqVHdCCcIt4nbxgxh2BVQ1sdqoBXiNa6yoDV\r\n8TTRoI4FTnYvEn2urcDErnriQuRahgPoC11AbtKjU5rIlXAFnQfxmgaDlSy0\r\npJ1aMQzd4euq90Kcd6BIRvfNFDSC+EvrV1p6ep11ZJTlMuu3VIXRmnGteYIw\r\nQRWg78NKjtD2LW9ohfKFS+T2pHCTmjXAOBz++vqwcyZ9PbzdOkeOm2yCm/Z7\r\n0iIH27+bOKT0i651VJ2TgwOLM8gwVYQgvgaqZE16JOYz8fjGzhNR/xBldFwP\r\nd/Pui1aiPYd1+WiikRouBm0+7GNCus5cZQ3aOSEyUoPdnG8Jdm5/xPD6RLsG\r\n04RVVWQIO91M8QkL0UhO/tjWPm+mochSvig=\r\n=ZGEG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.0.7811028_1652120729974_0.6260364930592193"},"_hasShrinkwrap":false},"6.1.7893410":{"name":"@metrichor/epi2me-api","version":"6.1.7893410","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@grpc/grpc-js":"^1.3.7","@improbable-eng/grpc-web":"^0.14.1","@improbable-eng/grpc-web-node-http-transport":"^0.14.1","@types/socket.io-client":"^1.4.36","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fdir":"^5.1.0","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","google-protobuf":"^3.18.1","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^2.4.0","ts-runtime-typecheck":"^2.4.2"},"gitHead":"14b6f70b4686eb11a10293f98e2dc3505b854161","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@6.1.7893410","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-FN1m3hqTE5KWOZo2niGKFCBUm3l7doSItEMRbIouUCQ7GtArPsBIfJVjbG8+9k0zB33KKjUIxpzkCpc1LFbwwQ==","shasum":"652fd44264fb9de301b92bd0dd554b780b0f131d","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-6.1.7893410.tgz","fileCount":372,"unpackedSize":820099,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxjEiWt2axAMCfDbh0V5ION0lnTbbidmcEGMwquJ7x8QIgUOHrqXP+mtoMLaUc7oTUdBLpNqfY/nVDu+0WW48ceKw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJig3DqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo7Pg//cCz/+gei9UspIePLuFH4DNr0eoxINDiuNRBvndT030TvRASN\r\nKyi02eBbK4L2j3jcpZLSTxV/Xoy0V04J0ohE53fIYYog0waHyYstDnOhKxzZ\r\nPmGSxRLFEJ2hkL/ymhyDrWVwuH+rrvrgaCel9l+kjlsEp/1AH0NW12fnPxvo\r\ngDnQ4yTpUeWO7eXXWgdVj6G86qhBmNk3o9BjWux5iXNDbW0iYEvIqFflXMea\r\na+8RN68/Z7CH9x9NJCvIRQ1sEurkl2VkgcO1v8GiIKn8jPeVQJPZbzXtxLrc\r\nvtBzVGmr8hsFgg4qmn5VfzxB/AaWG9EUnd1rt6De2+VdV75y8BXZPPem5czl\r\nAKY/+az9ZLTMXJ50cR4lzX79w32xVaD+IZtWzgU1uFCLdwmAuksx+1NKGeIO\r\nQyM/jcaSWK2cOrmpo0U0jwLdns5/8EBd52aZuBrkSNVsT+YwijvP0GwbRE6m\r\nMrNEypcmtBXQZWcHXqGY4HpG7VrUwRLGv0J5tpnNTcPv0dTP4jYZ9BcZqrUF\r\nVUPEpFdBofdjqOfCr70q0bajQxAPszMY2KosDM0n0+atupM5Rw/UESyDei/X\r\n1IqAGbWegTmzS1LeKe6qnFxB05B/1Y6uqQG/955ftN446uRcSdXPvw8h7rfw\r\nB4wu9JZOo5lyuURbXG0yhD6/XMp5Hw+U/L8=\r\n=Fns7\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_6.1.7893410_1652781290428_0.09997753959918398"},"_hasShrinkwrap":false},"7.0.7893911":{"name":"@metrichor/epi2me-api","version":"7.0.7893911","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"d27307b9cda7517b5b0605d1c736282f8d636430","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.0.7893911","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-bLSMmRSIUsk2h7FwoXnOGbN06tkCsAcJiLtpqDvrnm2NpM2DPNdjO2/QW88NNmiVvTr6FExbkhjLHI1kQsN0Jw==","shasum":"c3a7e7fb2b8a53e0148013643e071b914bb58015","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.0.7893911.tgz","fileCount":311,"unpackedSize":582672,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBhvlWgi2VWrkD+yFfYh5I5T0dvsN78cQBYUpXzHjqdUAiAyBKEfWqzEYTJJ++Ksgx4iYHrdf13IXJK7L4mfQZr7TA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJig3tEACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqZzQ//ceRyNm7xwCrKDpTbXuLB78t2YVaAwZDoiNcdR1xSfbZFNMz3\r\nR/9tTbHu+vNEqWp0GIupDdgEyh5d5JBY4YUkdfQCp5qqOEH61X0naks7iX5G\r\n/KquEaEPn+d2BQOnsYoTEqKhjXmCcXeXFJSMlthQn/E/prY2Nm9vuUVJCwYA\r\nPbf4xwvOzGsZ/mxXG7o7OEa0mCdjh5Akr1Cbxb4EOzV1loJhfHBViNO0JOHz\r\nJkN0odf30QG5V6YejF0/66B6jztN6tgQ4t4HcC/NN1zgweSMFxgpGhck5Odb\r\nrfs1PKMiiI8puNVymw7yPudLVpQNDNEk81M4r3Utwmm0xKJDwlDoKJjmH/TU\r\nXscYMZHG192J553tXxJrLfgfsxe7b7KPWi+fficPvtxQhi83TU+wqH6Bp6se\r\nhS/Q+aNjiqV4q8Vo+OkPn7SOVKcZGE1x9o8bGfbxSO1uIkKvrNMVNyEZk4nA\r\nMhCwOt+UxPKyGr9TzB8xVVWGsvD/XHRU5hul1BH/etUgBpZKsWPt2kiDXVoU\r\nvOsrk6XUEwGOvkjyK88HQfbimDWZFlHUMrrWgr3gnP+B/IA+/oyVs5Bz2u3U\r\ncQuiqi16PZFhun1Hrs7sj9qOQI8+nmRF4nefKP50Y9ridjJXVVenj4e/YQBl\r\nN8YTym1V7gA0yrUU54l2qF3oqGCpz8OBSC4=\r\n=iazd\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.0.7893911_1652783940560_0.6918482132642674"},"_hasShrinkwrap":false},"7.0.7974668":{"name":"@metrichor/epi2me-api","version":"7.0.7974668","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"9326e45465000300e8e1c45bb64a4a207b343d0d","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.0.7974668","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-lg6iZ+imVcH+dZdTIjDrTVUNqz+T2QKd6Y7NNM63qPSvLbTb+dOsh4CfvfxaZH0frvZlXjTO8SxXTx1Z7+yyjw==","shasum":"0470b2f7f154b45e15c1fec748aaa1be78aba7e6","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.0.7974668.tgz","fileCount":311,"unpackedSize":582678,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDlfyFNnhq++IV0BXTXqbKhlTviQZc/HwLHwGIm6WDYdAIhAN9zAQG91Dl/X1nR23ip12SP2fbG1UWyco3ZRbvu0FFm"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJijKDNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqr2Q/+PHB15aFQvGXiXnNB6KdYLW+5FsjA8hA9MNo0zvsgEYpuw//D\r\ns4xkk0huG2DEmFsoU+4L+j5uI0PSDOUZvWSgDICdblf8gMwFG1nF9rJCyDHP\r\nDR/PwOfv77DVYS01Rpi1JfbA7/peg95GClpjpbXgC3YcBzOHTnReaF9DSHYM\r\nv8asJk+45qo/x6xcGOpiFefwOwnaWhPHJe3TY8b5mMbAIoJRa1nGZRlVR1Ij\r\nJ+0p2cTWmiDjl8zRKG4JniHaYzxzQop5OJGhd7qJZHCKXuxcPB6IvQeJSRKa\r\n7D2s6WlouRYgO8HERebW3mtzgYSrVK87xxTRWVeEibZhvMtI23EnIOyqr1CW\r\n3RUX69N/21PvJJCXIBROuY9PUXfG6TWiehv6zLDKMvthiD3/z4DSa+P2y47L\r\n0OKjDo2bzsFeYVprQ1N2d+1dNomz3uNM2ilz/99wOEEYTI8C0oeiSVnrXVjj\r\nLFBwK+8A0tyuYT+AtGyjVF6NAYiuptNfvKkKEJ0LO0AbMJhY4r4LU70JmNM3\r\nMBuCTyEIub6mE/ZU3jGoQ8sVnGw5Ljhp7CBTUQLGwtGAMPy2xKHm+Tdt+lib\r\nw24i0dcN9ykm95jQLS3C81fra1vtfDhaP4E6/hg9vAWTB0vBj43iOCC05rd8\r\nRvUYYta2iPMHWE3y4L6/ewEOk+HKWDwgCak=\r\n=9T7o\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.0.7974668_1653383372836_0.4702147354734796"},"_hasShrinkwrap":false},"7.0.7975370":{"name":"@metrichor/epi2me-api","version":"7.0.7975370","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"e4c27e0d8936aaaa071e4f1a9afd09e1e91989be","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.0.7975370","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-7UzlBLvnLlSCXsVU6up/laD5WVdAXXXVFL1oMJ3hNyPECmWWC5bmEFY1RZ+W42TttSw+xCsy5geNgRLqjR6/NA==","shasum":"219e2a0fbe42b604e1c8195f13927d612733efc1","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.0.7975370.tgz","fileCount":311,"unpackedSize":582678,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH3h76NUc8246fb0NBgAdHCo1/0b3Efchg5zthO+4YZPAiEArBln3CWwAKPgEPkZOZp40mUhz0Lozaip2yDHQVbpiIU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJijKm3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrczA/+NTkbtsC9PDuvSxvN5xCrvb43RZqENTnAQ0T6Ly+K7DfWXeFr\r\nZVYzi+BSd+XaHIL75X1dnTxxHBX4J2sXCnKA1NUfA6T/yUIjvweBrJkPkXhN\r\n2856uvbJH4ZFzIKbUnKKirEqBR5WSW3rKXSM5vFrGrw9xgmLcfjFEDGpxMq8\r\nps3B8tci9CfygdnzlIWWyvLaYFWJvj4ekceXohTJnfKzury2C0IFaxhegLjI\r\npKXSJW3SXxnqtrS7e5VcN7DiQCoE/3u8CKkCLgI9xfUlXsY6rY97AWe1gDws\r\n6RHQPeh72isbXp/qwzLQ5ac1ksSaGFnsQz6WNXDaZEjJjJeJbp2ZNdjvxJV4\r\nTrjrETZpoFfOqcFHpwxuZL8xGuTmMNfhtVbynSsKt47GKfVlBWOcZjQG0Zn/\r\n3GSikOU/W6s+Qajvo6LWdSIS5rjzEgE1HS2KoKO0cJRMCEeTCXY3gH5jAl7D\r\n0ACFTDgrp8y7I2VMocV7lvZvBM/gK/yazxuFQ+pk8+z6SYI+pSWYWtMe0Oj8\r\nOuJ8J1ofGCQb0gVIP8lKsGmGPNBCLVfSNytQRXYv6BeQwSc8GKsSJtP+qqAt\r\npjbcyL7MIYjv3OgQ7xh2XMiHHCypQr/8/sLiBJ8BBNoemmT94rP1nhcPhDP2\r\nsJreXMAXiNURXDtzaiSGBLBcuUT29Lvv7Yo=\r\n=7pN8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.0.7975370_1653385655600_0.8994464745511568"},"_hasShrinkwrap":false},"7.0.8286949":{"name":"@metrichor/epi2me-api","version":"7.0.8286949","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"e4c27e0d8936aaaa071e4f1a9afd09e1e91989be","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.0.8286949","_nodeVersion":"16.15.1","_npmVersion":"8.11.0","dist":{"integrity":"sha512-Kvz9RhCrOWwwGhJXgcBT1skbKS3pAZNbLr03u6snrvmZ/IrG1wJyx4lGLGZWuM8U86WuuENjk9Zjj1zC8TQwiw==","shasum":"f4f5e4f7e397dbe9132a73b8b713917e4013feda","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.0.8286949.tgz","fileCount":311,"unpackedSize":582678,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDH8LMmMEQ4lGiYkRe5tgmKflwBuHQO6EC/MmSsK4yBdgIgDQ50U1cTyqEOeGcx3CUncj61RpwOb5cyn9J2FnKCWnw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJisuFzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqTGRAAl1Rc/hup36xLza76D5ZNYVL2NyF2E8Jjo/MPNHXXMYGTkmEE\r\numbT9ovJF22+m/qKs7t2qVfyiaDtaK4eorKLMACuIsHVC5pStNicaHh1xPO/\r\nlnDhmkTrB8Wbi8jlzN9DIiTdL4e4zPG+GU75P/KlTcCtfGiMPoyUfwlT1+IA\r\n6ZTsez2FQxEFiSplqcQLE+QKaniJWcJAJxz8n9nRwb9PnlBasfASs9LhuyQr\r\nb/vKWIC4plMAagz7kk1SBcKGzR+xJjxsIzQo9hQ6WDc/o8+ru4Fxko61daH/\r\nl9tS08aAxUYCavAi7SaTdDYwYosgXEnEzECRkjkgfgm1ifNIHUtCbiMClG9w\r\nXleV6190wQ740exhwpcHZ31j4aGsttSJFKg5PPUL/G58awOwCEakb36hAwZM\r\nE5/JM/2vpKzF0xMJJdH/zJkgWykPYvhfsrcScpefYjUneb8ejKTi7Yy5zVRp\r\nkQCol3pNVYaTd9VW1niYb9gaowhuc3BogxgX2X9DVYiunRPfrrRukx2TdsVD\r\nFjxbePzlYxu/BMFJYyZIe8fsUKwtOioZsQ7VsncEL7NoDkIuyOxYdClXnJZZ\r\nbKtWCBK+WD6QAr0yTIkzBUgkAEWp1i0pns3AW1CSMYPktmgVSnSOaZKfhBiq\r\nyqV2BjM4S40GWCQF2NEzoEoPkcOBsdl2684=\r\n=ou7U\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.0.8286949_1655890290852_0.2788308993763038"},"_hasShrinkwrap":false},"7.0.8293283":{"name":"@metrichor/epi2me-api","version":"7.0.8293283","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"b33037570d713ff14276343e3378bc9d38390d27","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.0.8293283","_nodeVersion":"16.15.1","_npmVersion":"8.11.0","dist":{"integrity":"sha512-lTkqp0zqyZ+EUwIjWiqcCuy7+iT28peD2Hl5JEiDsHYJ8Sf07sU8mn+ROJ7BeBvXEMFpdxriNNqCkhBT6/t00A==","shasum":"83be75906192dcb4a62f858249933d962bfbd6e9","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.0.8293283.tgz","fileCount":313,"unpackedSize":592446,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDjyXsrf0S73MfFt1l8aKFrIMsg3tsdvqFONFREDvpsigIhAObtEDPZ6cHepbg1G37TBRGfKz9538C+FtFlbGntyZ91"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiszS9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqx6A/+K9M9SCKy4ydLaH1umheHKODhqDgzxlbXolLmDDreV8ptOtkM\r\n8q1HbJT/L/b9GHMnmO0uCxrHIvdPgQ3Ms3REW6E6GiX2nFzqn9Vst6bVLOZ4\r\n4Aimd6Ptpu0nWe0K1pJSdoelV/DNC98XnvS5f59gCoHso+S2ynkM9GgUMkSV\r\nAB10yPinr2dtsVBC5IA2GcrEGBsDMfNNI0OwwLUbJaMy88W6Ygbs9KnSbokS\r\n1jhUT+iLp/sxwUB7qabzyGmb38Q+4FdEPbIfiMPjMEXHzudjlDjVlz1qZh9x\r\ncH3awYxuCQ91MLs7kG6qScseJoXRN40CNGdi2swCeHouiC4DN0XhZb6FBCmT\r\n0wHAG3H0i+UlQ4TOfSRDnVuZ2yGH+fmRyQ+talZnQWJrkX1JctXtRXKPrxzd\r\nhFZPT0K1dinladz7OxjlNfdIaPUZ9NlOZtpHi8cRoJpmqMqxE/ROkaA2zjoC\r\nNaSAYWOg9+9bC9Xz+8byAGcu0y6mYqum60F+VM8yANhAgzGNm+5kQee0WGZH\r\n/4GhmTVgvO0nC4lrYkXW74V0+P0WbG/aufrgeOj88NW7m9w+FRxZiauS+k7D\r\nLJyX1kYp2p6CD/8W4ZHOrSpbnH9IDC0zbBHM44CyKal4i3VAh2EHe5XK8Ezv\r\nG/MmOpK18ugbouuutzzG9kB96ou3MKDGgjU=\r\n=HXEd\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.0.8293283_1655911613580_0.5467329850726454"},"_hasShrinkwrap":false},"7.0.8293242":{"name":"@metrichor/epi2me-api","version":"7.0.8293242","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"834ab266bca55ba771b898fa80081de8612168ff","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.0.8293242","_nodeVersion":"16.15.1","_npmVersion":"8.11.0","dist":{"integrity":"sha512-TmVTzEBUYdqlnwrkMSOPuA+8vq758hGQEND4RDJ4YudOulVozNOUZDCgJduz26PHeul+BhYoh3Kaxnp59QyJyQ==","shasum":"d4b6af0ddefaee4045a031f80422bc4f603783b8","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.0.8293242.tgz","fileCount":313,"unpackedSize":584156,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF7bugNDTQnhMjLwhajn8yg2JXs7DA9fgbDNyDscDImAAiEA8noaSNhNZzCivI/YxOiwhTZX123JNom6p+fhOTmNmkQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJis0DuACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqGoA//eUp66Qv156GZ+caifh5ilA2x8iD1r9SHvGQ7C9hnTP5e/Vng\r\ntCa+2t+l88A01Y3Z/snD+IUmQBd9rpdQL+pISL/3dYYJ/S/9oQ/icj05vPnu\r\nkEQtIffAvILeJinl5zBg40uYy5RY0nGDYnk9KoTJMJxx8f1SMxI2w+/LXJ4q\r\nKagRfYgNxVNnEkZk0mVs7PTKSPRWmvTWZTISb2RQALCxex1lvSO4GYpyvqAV\r\nQL6dWEP+XS5FeL/8cKd1E7cOvaoeT1BJVJURdwJ37qdj5WDiXc2t9DzTYsrq\r\nEftQCZFC/NkvloN1ipIcasnjnaKXj3oCTuhpDhJ/Fp2TRpBXBBDBCK+oUx9s\r\nBMlsMAa44pH4qr34iesAh1MVyNIfxcg1Qr5Ax18Vzy7n0+CSAjFZgRnbOVjt\r\no3GY/inFUo6RPOLgKAB+vK9A3mSVsrbnmL1ixqy4y0hRt7qTYSI3zVJ27q1E\r\nYd/SIziohPD+M1QPzo0laJ6HXIO19cfcuzeVJXKQpE9eRAnVN3nEacF1x4lf\r\nLaSrc7LVWJ3uGcQ/wRSKFiOceexQ/KYyI0UxtAdYI32G7w2y95tR7UDePfw2\r\nbvIgY/VsN0ZuX5U8KWKkSJ6SNwWXNgWmUMhQ3Ow0YF7EnnNhWGceC+O7aGLv\r\nMThrPJTDZNR/zZ75vObMCou5LrJbpTDIlKk=\r\n=4lor\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.0.8293242_1655914733863_0.1503389456953299"},"_hasShrinkwrap":false},"7.0.8400083":{"name":"@metrichor/epi2me-api","version":"7.0.8400083","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"5621f14e53a606085bb279adffe26bedaf3fbb44","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.0.8400083","_nodeVersion":"16.15.1","_npmVersion":"8.11.0","dist":{"integrity":"sha512-1dRmrh98QeQ0HEn+r54RGbuVESY4N/8/Q9c92/RD+9N2vQe9nfMvjj9KhSy9T+oNE6G7SosBHcyzV3oa5cZHlw==","shasum":"93be433c8cd454ee34e61605c3797017f7b2aec5","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.0.8400083.tgz","fileCount":313,"unpackedSize":592434,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOajuqEir3xlojGvJz4q47m8mWvtxqQWUjqtmf9BH35AIgXFUoh3pgh2+QyWlJybKG4vyU3u3YV7o7YA03JAgoq8k="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJivv01ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo4BA/9Fb1jxMIieZ0vXeQOX2BUxat3USsApltgFhhaCiKS2MRZade3\r\nYm/Sy+0CgxIu7gvIYh/S/96yfJ7/ba5EuxK6s0oO63IoYDK6MyU/rulrGu3K\r\nX+Q93NMaBcffb6V5B8FzgXfl/VFg5NSTHdoHiDdq59OD1PorEtKaNed7ETpG\r\nOTlvqfb/ReIa79gNrcXvM9Qvlkgr5y7yHhbunUi/8Yprm2EE8suPH434mLge\r\nAI16GY66qSOHKkTbR1kxKj5mme+0XZiJzPUFzCqZLvXQDUGq5sUGNAqAMa1r\r\nriZPWtuCPD1DNdJExj6OAE3hlyfOhC5vqryc2GOerJA0KGd5qpNx4NLrX3Zh\r\nsUwh6CxJVE39graSccFF2B3AscHVAt62fsvfUFoniyKumPU3rvxdD4jDId6k\r\nrDRM0yVGaVl2Mr8pcT4DA+mM9o5su7hamU3DFVeqxKjqPCl6PgUH2qHFYAAl\r\nmisDkU8banAGgU+mhMTSee8bdIVaSpMxgPUN/V3xSO9AsbMeb3qbgTolW5xc\r\nWY43mWn2RV3Ko5vS9Gc97JvgTq7eCcKNvjKAjAj+ZoGdWnMFAyglvXXP/Zn5\r\ndKkk7zYSHDHJV0k1bHAaMQ4tT8PzEb5iS4PguSIPRVBbW2w5+ENVVS3PM9XV\r\nth2QQ4eZDLeDxiA8Xst4Btm8cdHa3WnRIIw=\r\n=Cx3T\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.0.8400083_1656683829623_0.44528913170669204"},"_hasShrinkwrap":false},"7.1.8860292":{"name":"@metrichor/epi2me-api","version":"7.1.8860292","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"c0873c7ed65bbbb08a661af69f360f0aa7e238f4","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.1.8860292","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-Av9vx0ue4vzQ98Ch//6sHJIUXlL1/J20OY4r6KTlGJuV1tRMVjPAdzrGxzVNb1kRZUB2NiohjxdDTmND+mYEXQ==","shasum":"168254bc11a23eb205945ef7e807e9bd32568950","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.1.8860292.tgz","fileCount":313,"unpackedSize":596008,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE7oK7ib8cTtIR3BOYIij329bbqs4w+LQESCuqQK2FX+AiANpym2cQP5JfAz8WUVCI6ka7jQvDHjqHlgHqMvHmiWMw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjBjZAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqHlQ//UTM9mZ2hGzmLp46jfkcsILloppYyVb7gB9BAO1ZbPndMcjCZ\r\nVMQHXUaXyUfp7jxAfayuqEorXm24BeC6+UoRREyYJ9bNxFYaHwZ5Y3KyWpVb\r\nG8Cog0OfSKeBZ8eKSbVebH2trEsThbGYU293eTDkzbF9FeVobA483wxCnFt6\r\nyOVrxEKnyvJe5mYspwt4d3if9HU0IErETI5gzMYNCSqChkuCm9PHh2NC7wB7\r\nrX4VSO3x1Bv7vkuFDLaqEbaespDU8DxcLtZwVZGMU4TFZuemztRncrjrKXAj\r\njqkZQpqDXzRHwYMLYWcKtvIsR0n8tu9QD/Jxxt4ylZZsgRlX5SaWfYCb/dCw\r\n36z9Le8o0PSu2o8BO3A8pQYkcR+Qpsc8pdocyItbc9Twp68aa1vv3DI99iLb\r\nGYC2V7RgTu4HEpNCApHeCuIkg1ztTo0WszuFJYwetn95pDpN7VFSIw6G0y1R\r\nZBA0fMSUp7xtic4y8iqnx/x7nevGGZHpMhhVluIaamC7RyHzlpDQANU03Hej\r\nkZG2MG7efqcbZ3Ph8BC2C0J1ElvMoxHZW8XY6FUe2bVOiuCVDcg6+Vzh00Xa\r\nG8zxOVtNmisWrqtOTsCKEu/ggXb8BRc/ROGHTRV6iaPJjm+seSfStd9mlLy4\r\nz8FQWcOB0mjbiQgp937TqI9ZM3h/z6S8eiU=\r\n=VG8L\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.1.8860292_1661351487728_0.6490815280249751"},"_hasShrinkwrap":false},"7.1.8934394":{"name":"@metrichor/epi2me-api","version":"7.1.8934394","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","immutable":"^4.0.0-rc.15","proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"2b0ca9fa5dfe6441b157ad5454275e807988aa0a","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.1.8934394","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-dImcAecjTCEpUh1FBn5PLASqcaqrJ7o/cmDTYBn5ve/IrRxi5XNPTcOMTesZ1Fc42xm35gSQ73rM/k0fpp9wwQ==","shasum":"b388d05277b6afc5fbd0bdce76fee0e3e535cf7d","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.1.8934394.tgz","fileCount":313,"unpackedSize":598286,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGaZEPppmBm6inmVMdBxfkID246QmcdMOPMIIgQWdlggAiBv46RdHlqanwvU5VhTjFKZrf7orgwJ+38mpQ7OTbwg7A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjF0cEACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmok4g//XvFcQXRGxvueYVZcOH4HQ3MJf+rojOO83ppZ3T8+lhTBnkLP\r\ndjSI6wUAL7ZiPh/m+gaXQSIQaXeLmrBpZLOB2XAAM6K2kXw1/AIJdOtDxPdM\r\nm+b48Sc4mQaPwIQLI0dY49+wAKPZ/pDbhJMFH5/sbOD5vCt4DmtV4IrhxZhJ\r\nKvdSZV3vSvl/NV2tBf/lsP0myGaKQTgOkcQa2zgbkfuLMQU9tsC/CHHrz9d6\r\nAXNo+6Aq8HkbXlLHCQATISdQAeTPdil8UmtqRGIHZVkire8kaxBWjI+gI2z1\r\nXIm0jD1009ZlP6r0NzFCl0d656JlHnasgfPWS2XJNMtGvj+yxT5v3X8ThMLc\r\nfYG+CuD7wdRmsjQyj1JKwqhNb15jradS7kCMiw/mQvaigo32YM5RtEWrwMlr\r\nd/8fb0KFHag/5h5zI+N0Y1d5USbEGTdYTPWo0hXBUsinOgymp+f0DbXGcbNu\r\nneQchFftVF2hN2Qr6n6NIa+1U6T11UPbjimvHhz1OL24h76z7biYDjpTHyx/\r\n1wLNc086LN5vzFtmuoWO3PssJoJFhQG3AGrRE7txRFHEoy2M6qtVykc0vYGn\r\nKIQoI9gSUv7gDQeOauCmkr+Csy1J+g5cbrFZINwsfJDTnVB02yCZb2zUBhGv\r\nXvXCpjWWuqK5uE/M/xOwESqYBK6rrQjRxWo=\r\n=3Aky\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.1.8934394_1662469892520_0.11246286317150211"},"_hasShrinkwrap":false},"7.1.8949394":{"name":"@metrichor/epi2me-api","version":"7.1.8949394","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.3","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"d3db4694f2c53b6e423bdad635d2515bf55f108b","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.1.8949394","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-VuPbNXFztPp+EWowbsRetVDGxGuWaEzJ/aT7AVBw51GcZpPGmYRM863IQF1J7Cbbstb4Vfcr/efFXZVCpuDPfQ==","shasum":"9826c69b952c00e4779f48d668c39caba671f3e4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.1.8949394.tgz","fileCount":319,"unpackedSize":602020,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFFcPnaGPJcc40HlyyyrDeHPoVuvx2r9SKeadyW/CcluAiAB8LWjD75RDNGr1K2m/z0f8GNXX/iSd2rGwYFcclKKFQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjGai+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrqYQ/+LDpkb/IIvq7v1pIvYkXEgml/C84jMdkI4zUcFf1uJAMf2NDV\r\nR1tVJdqsz3hClESiYqG1g8fVG+ArR//YAQGPL3WKq8OzqzS1NIXjdkAtLyG7\r\nFaDspT15K7r7Ygo7tAlRS+eYebrs0/uiuTIW3QshtUuwNP1IBwDBYXpd0prl\r\nhH3qtwTb74xPE3txyd/8LhKrUS4/TFmOp/MJEDTIGKE7++5pDLlxqPn82NGl\r\naH52n1QZNDWbaPOx2FJPgHp6vP1UBFzJVjf/rGHGLBcqhj+UGBTY/A8l/sIy\r\nXxmGUo7JOup+Jn0LPPWUZlYGaoT6eWTSO/6JlPveHW9ZzoZroxGuH1AIFxOe\r\nT6q/atOZj1GRoHUz+7ItRuvKocPTJGVfnMAgAktK1gVS6Bu7NjlAek4TkqeV\r\nOHmiYZK8HJvUEAG0OHH4SGCXT8O8ZNgMA/MTK3FhTtTLfnE2hhwdQIep2Hjf\r\nh5qSad2fopDXPeGO2yBGgK46c9nqmaasb+w9JyUvttfK+dcUTW27OFCTKqM8\r\nWTecLM8YJFXazOkZH00eaNqoG0HD9YWUJlqxPvdfIg2mfBvmmv3HTl+oa2Vq\r\naZqhWLNw1fXLlWUOITZRJ0ySarAPUp33Ncq04JgHhcgvsWw8Kat8goghxGfT\r\nT2lNTqavB3WM8yoPdiOCx8kDQL044s1uzvs=\r\n=idEy\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.1.8949394_1662625982215_0.5057048031513625"},"_hasShrinkwrap":false},"7.1.8949620":{"name":"@metrichor/epi2me-api","version":"7.1.8949620","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"e7f19708d023dfd6c55cf2aecd47bf64a920db8b","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.1.8949620","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-kN6QGLHSTsfeYdSWnIHEXR/1vJ3P6PKK0t4nDLCtqQXE2A+tGLbVH2LutJp+PId+Zql7/nTwsa4YMRaoHixehQ==","shasum":"a5b63c8c159842bad7a7d5112b2f991b8cb25740","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.1.8949620.tgz","fileCount":319,"unpackedSize":602008,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDfpbeXqM+EgscEmBg94RCkUSXMradK/nnXDVNRyZtrHwIgA8ZyNn19NSOkEBORifc1IAFZmosJu5PF2Fbh2Nj6nHA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjGa60ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqewQ/9HLrH6wuUztLNzfcE9gMFjC93CJGj0evQeDjHmhtyMhx1MK+F\r\nXdTZINxsPAAhdB9Ui/yAkegUzAB3wKp164vk6O4VDb1UBQdYyInBQt9dTNSz\r\n+PSLWBG/OxcpoXg56diFqdOE+z1BqQ3UQGa3nq+cDyEeWYFX9LSYrVQZEHbn\r\nhSbmi6gDIQZrWpQ6EH6GOFI70edJcZ9ZrdLu+jn4XMmK766SvNQykyOw3aV6\r\nyxEOGQqCLp81TuB1++NVmR7i5YVPkB/wyR7JRRMh2RBixG9Qee4cg9v+GR/4\r\nfHHd5Nc6ZUWR1PWNj7amF+AHoPHpTLGZANDrCGpZWrjssquflyjKmvz/M4Dd\r\n2bxe+o4p9eGsKCLg8ocKrs1r/rWVM/rXWZcb6gkWzMz1lk6apDRB6UAFJJlC\r\nAB7Qw6+ngs2IgYKqhAAFOiguJy0wvy7nfHXyPvGzWzwLgalCNa1kaZ5F3Qaz\r\nYET/zULd3N06pLy/zAYO/I6ipbetg4pK89lf1byzSKWwVZ8xJF7unAqM/a0d\r\nSX3DpIEVBW1JWcsBLKrzrUto2FsRCVQlhlP23kRNxzKabWWZfuM9FX6nBhXN\r\nNcXIK7lHkF3ttxrILZ/VPGeU5pKStJ8wUAnLF9PA9rOELaQsiqIMED07CvHm\r\nhd1s+jupiWlqhqeyi9dqahIn4FniTcOwUzM=\r\n=4+pF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.1.8949620_1662627507876_0.1928425873055839"},"_hasShrinkwrap":false},"7.1.9018732":{"name":"@metrichor/epi2me-api","version":"7.1.9018732","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"562dfbbdc6116b89a0e3822c89ad1e694e993c6d","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.1.9018732","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-3aY7qvWNLICyZXsFgjPhYheQ19/ae1KKqX9Ao7j7lZgQsW9ElvuNqr2DCTU74ZkFkoHw+UZyGNQxCUG2Cnml3A==","shasum":"ee3fcedbba636a85a36d8ff1befd0495d405100b","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.1.9018732.tgz","fileCount":319,"unpackedSize":611215,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCaDjs6C2qEAbyb71O1ub+TkSgFfJpPL52cp8SEucfFfgIhAJi3uDkeURBeQBTCitGls+ScmoQfY7KOjHiCbSy2V7s+"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKeHvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmohfBAAmwp0I9l22XSk0SCWtmaMSzPGeWxFxV5ezzLtIZiqVbfTCTrF\r\nBDt/GLofEo42/qSt2RhsLwaxM3V7v3Oph2M+fhfwuAAd1SW2f+FhzBZs4PSD\r\nYxhlJclVzhtiqUT5gnBGxbjbPfat1HEocE63JJbobD0TvDgq0f9kXNERB2hJ\r\nXgTiOze9tJWIQ4CNnL9TqQGxZGxHFwt8hDUUz4qjgKz6wLhPbxcoQ2HiKcg5\r\nTtRG90mQKExy6GLjk9IlCkM1eOyrXqbEkmAzk22BMAeqeBYYGkN7q1AI4spf\r\n0Ay8QI1g9AT4vDK1H/sC4UQ6e3ow0FanYomc4qtd5zfWel1b9lubzl4jeWQf\r\nAKDHLLANkMe2ayZRpQ8sDq2CvQkYYQzg7KIlMepyOtuLww0Xyr152VoGMQjb\r\nLbYr/UvVCx3Q8OddFQ0bUChQ07JrFZJ6zQMO14g5/adkDOzvdxDRVTDCTUXM\r\nTN+xUXm+1cNIyofv18OwlmfP+IosHN9KVhZWcpGho8zMvIqmJZ4GTDkSTugO\r\n5wkM93W+esYcZPcTMuXRBCPCBtryHVZYjsh3WNPMVPesxN6v52mbbaCUWFXf\r\nOFH7PruyXLsF/nSthNmpdTR4YQVWZKsXDp/a6KeJPmt3bOKx0Q4ucML6uWIj\r\nMgfxJzDP7Oszwe9E6ho3mmdliDdNNk69UBg=\r\n=tOqP\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.1.9018732_1663689199127_0.08360869280771377"},"_hasShrinkwrap":false},"7.1.9018737":{"name":"@metrichor/epi2me-api","version":"7.1.9018737","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","axios":"^0.22.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"84568606c8af1dd31f889c2e4b94e9c181bf44a4","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.1.9018737","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-ymOGQw6bNPI00J84IFVaosBRQjQE14dY1BDls+FH95mW1qftpSlaD8cVKDOJxAdZDQYEypLdLL2ANFXjne3z+Q==","shasum":"15ed0ef020c6594f8a16721b30e7ac218f9856f0","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.1.9018737.tgz","fileCount":319,"unpackedSize":609325,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDo0gcyO2p33FLuRY6u3+WGaAuGKUNvbu91YvaMq5qy9QIgeJCQP3O9E4t6sheAlZgNWlNy3jA5WTN2i4TUXyGTMEI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKeH5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqAsBAAlT3+De+5EP584QxKVTNY/Ts2M9qzecziIXVx8XEtwSkPEQJa\r\nUlbTCG+b4TIj8V2nTqz7EGyzKsxyUMY9jfeMiDAhdT3YYpVszS+w8nuGKk56\r\n64sKT3to7HnsPHh79H+dorPzBDt+lcB9OroKH3Sfk3fK2dO8SuXbQhc2fTHS\r\nW6DH3Q1sLe1g1lgb2Yk5EBNK2VRiiOv0EsG/b/w7Eb5KDrSX20ZcD7qVPqDn\r\ndXNA1D9484SaWJ9jBeux4Rx4/UbCp9VQghJKjXpxhQ1bK53b1zQ5kDqZbUxC\r\nLh99iZcmvcfqWo50o6AtOTHtEzpQ+O9Ln+Hf/z3YJUre23weWHdOV2zK//04\r\nBBBMl2/+hzoNT5sv06I82VYEX44IlyvH6bqHxY7VjoqtQkBqfyrUU7iwFCjl\r\n3E82tre8Boag7o81UpF/HivKaXdrZDHmAnOpGxO9lKoWAOYeTQlTqydRLdcY\r\n4EWRIHoxp0NN0GxdwT5pECiHopVCelDm1HHf+fG6A7OeEVn+gkuMdzQY/b60\r\nG5uSnhEFZxsegnR5X2ckDt9DAeKMPJCC938YEJKCuykizU4Qnj2rAPbAR4iI\r\nAFjG9rYtOSub0F+VhLk0pTcbldCGHeXMmXbvL4K81h+0RqLArLxpigpWKTVI\r\nZJ4c1IGmK9alM388oU5hmwJLszVSP5eGktU=\r\n=PmFe\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.1.9018737_1663689208754_0.9538124577994322"},"_hasShrinkwrap":false},"7.2.9018966":{"name":"@metrichor/epi2me-api","version":"7.2.9018966","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"e413523cf7b71232ff735b82cfcf5a905d46fe7b","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.9018966","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-EVCxg4SvIW8XP7Hkfqg70r2ak6WvDa7UG+Q8J3vmQTctPAgOMhH+MUsfe96sqz4WujZ5nxs3ofB58o/WMSVZqQ==","shasum":"12f04197070f51626f7ac48875b15e8000f49b74","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.9018966.tgz","fileCount":319,"unpackedSize":609301,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDRshh6mkE8wW7EDin+4AwmipKmbHYoSOKxc4MOx4PVMAIhAPH6fiumOkCQYF1Xxz8TPk4ZlQ5zbPVQ8Qjzmp7xEyIO"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKsgUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmolTBAAjAvbYYbefEeJoVvvYNZ17YRQutCzZEOq3usJSAamRJ39aQph\r\nZOZLdM+wivspgdSTCwu87JjsuPbyXCoJcenYJZeLf9ORxC+elGiPtsI1qyoF\r\n8kTMYX9pBcJsWwi8WlqRgDKLGyOGq5ylEft5NOPNHwSQ9FH2u36hfilv34Tm\r\nnNVZAk4XqJcwyFDBY+WlKhbSgClxpnSjqJkHzUX1oMRMbqMTIVNHDCZfNaBL\r\nKsmdRVSp0kv+7FiX7mluPdRnUmPOzvgftwWA21NiVb98Uc794+cPK8op0ZMp\r\nsexSn9b96pwRMgSLmVSa1PdZ3+B0wTtJ7/EKjlyJZ9Ayxx/BNqssgcrjyl8k\r\nZqCQRqXY0n7ICaQJbaBMib7T2DXWq23YH1h3i25ujkXLfxmuQpxkEtEeyKqy\r\nX5r8nxi5iSCGfURKaiMNH9mD0JoMRcaOdeAeacvvpmQQNRyjZO2mPLuo4WXY\r\nPN+JVF1Yu5GDt6z+rMbAqMNWmkH41rtob84GnzVcVV5YxYcUBxDytTga3DmQ\r\niEJDgBfcWUK76lkAK4lTC7SqOSfXLArb3sJtCM7zph+j493+eVxbm9749WsM\r\nsOGGInOx2hquWDJJ/OVN1VRHKC3v4vGaYTu6nm62A0jT+fGEetY8f1bFgRlO\r\nGRTni9ljIDXH8DsXDYzUQ1VnImFjnJ+0Hlk=\r\n=qLur\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.9018966_1663748116297_0.5585455871538838"},"_hasShrinkwrap":false},"7.2.9021389":{"name":"@metrichor/epi2me-api","version":"7.2.9021389","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"13a85509cd79acdfba8af2f15736b749c883b005","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.9021389","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-v0EBIP1/VStcott5mhP3iT1yLfDnLA0h8OPfeHwUnl83n5GcLFi274u3z3nDoijqyJwVN38AyVRSW0BDEPA6qQ==","shasum":"377a71f9cea7ff1bfc34dd83a2f83878fcd0e2a7","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.9021389.tgz","fileCount":319,"unpackedSize":609301,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEMCIAyTwDPZg8GeXf1BrjiDjxAs/abEpDQc6Kp8ieOzqKfLAh9gmghMc7J/+hY+iRv/Hb/I0V6a4Rb0QGKs2C20jJyl"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKsmTACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpaDQ/9EszjCvz4vRPQA9/OEYN1hBHgQcU+IUEi0Z53slsL9DiReFRA\r\nhOild0jJy78r+1Km+KclPZEL3pQNVbmZIXE/ErelDpYu6tasUU8bsRrogMxo\r\n099epJMGqHSPqlvRlucH+enc1MXZ5jzf6CdiwhSQwVZHyCQCj6+C50haTD5O\r\noeV5O1nOPtdBXuTRDOUg6pOj2ZyXZptLogx0No3sToCzEeWWIiENsr2pYAEs\r\na8F0kICGilv5IqnF/n9zf9bVuM2ImMJbamkhWZSONMFlOSVb7Z0egLtZlajy\r\nKRQC0FGcDavuX+b0GtaHg5owcVzBlL0wh9mdQTdRyPq4GtBPzwOKD/pLxzzC\r\nbm5qOF3JPHD4j+vs4HIPA4k2fZPhlf6zH1zmI/G1zr5pwpOn73N5z005k7Yt\r\nzmmzF/bWAYqmMbxZLfYi6D1SSPBWuu1NZu5VMWPzUh8jzfIOdb6tD267N/1k\r\nQuStyxKAO3bK2yhIhsYR6d90GCx2E4ZhmjtvjSpkmSPjz1QqLtRzvpmD1qWn\r\nJFSIoaP0IuxnJqP2pRYztV8nfkWtcmIatq2B66ozHayqUAZoOBuPINL5Gtdj\r\nHkptyW0FcGUsb9jTYxa+awPWwXVF39Zyo1gx35uh0dGhV9xJHPhjL5bDkiGB\r\ndiY0SRqRESQCYnIsxx4uNjcBy6LNzDw9u+c=\r\n=jz+c\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.9021389_1663748499216_0.6378313608201069"},"_hasShrinkwrap":false},"7.2.9057104":{"name":"@metrichor/epi2me-api","version":"7.2.9057104","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"8cd8319e9bfe99bdd0620543d6f6d55b5a721ab4","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.9057104","_nodeVersion":"16.17.1","_npmVersion":"8.15.0","dist":{"integrity":"sha512-NSyXiJ5iFpUeWNZu0JmddxgFv/+74syeULpCEpxCy7CEzawR/odInfB013kNjmVb56NZGfdeb+xMPvD7lk4Pog==","shasum":"3c83fced6b652b9de7c940129c2000c26ca23399","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.9057104.tgz","fileCount":319,"unpackedSize":609301,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC6+YU0sTF8B+e4kpS7YE7UAajTotfx/sDguqmuJHqtTAiA+Vyj5KfAMQUqPZqzNmL7wD935+VUgEY/ANQZhgxiSsg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMtDsACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpgSxAAl8QVAqAdBLYLGv8ZnwF5JQY5vxaCJRbzJ5W8r4MEq8PcvQqV\r\n6EHHcPfbyjuNxJyP1Nl7CmpBeMwpYwjVpjrdO/5W48NVdq5YU8PFy/jnZDuG\r\nPxDXuxO8W2kLTNkfXKeqb6snsxXq5V0SVAJl3UgV927/wDhhA7G60pHjYrgx\r\n5pOE0fCyNV71gEoQqNmMFzB7uMtPnog7+LRNYGKkVXeZuHBBuGTXaCHZeyNQ\r\n2mhk2SgEGNQqauNQQ7Cudm9yYcMpZasGQoWDtHa6xEAyiv7pHTwuK0O22AD7\r\nr4+X8zxM8DHNoDurCnUO9BGbNKzLp9z2ChXt5T/dqVzMlBlNQk3CFeIikp3w\r\ngOqbn3nXxK3NRnP8J9sQO6emE/TuPM6+QYl56NhYTyBaP4lWyYXKimhypL7n\r\nsB88BIU2POGS+d9QQpanlCu5AWO+CBzQyBsmFBL5SKktdMg3/XU5dSi+BGD9\r\nBgOf2dOvJHFsQgOiYE9RENGpA323tEZ+JfDt/a291dmSEQ11TAeDwmMfIgMt\r\nKgkOX6LG9rMsE9/QBK2JZBZIagZb0MROwcuGVM2oLAusCptZrZ8PC/rHfLW8\r\nvd1XdI8SgCLbuUMhWOTSJ4j4TXuPFwFa4FgFAHAlBJ2nCwJdLCOiXIq2Hl6B\r\nExFd2l/lSxt5v4zjraMyK3mFP/Q7xZtRJr4=\r\n=DeS5\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.9057104_1664274668337_0.30332932377675914"},"_hasShrinkwrap":false},"7.2.9453780":{"name":"@metrichor/epi2me-api","version":"7.2.9453780","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"edf32c28ec61493d7fe77b2897c2f866cbec4482","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.9453780","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-cGMEnY8h/jiPHI743jB60VsYPtLnCytF0nd/BrQVFC7Ut+IujrQZ7F2ZK58unHlD4E0UXlt0vXzCs3CMxXxCDA==","shasum":"8607bc33aec1c69d4494c4b5905aae4d18db3fe0","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.9453780.tgz","fileCount":319,"unpackedSize":611020,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHn7TVSMQ6vLbXMzp7V0lLUK4OnLc7vFnV7DFmKJl+xpAiEA5d7abWoqMGBj9p1/w9pEYX/KOCSgU8qf0E+RCG51Kt8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfNdfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpn4Q/6Aylm7b/MEnlXEYlvUwDTANQYXiSTIXFi0ELhlF6VN3thCcgq\r\nnzmo58t6kZOm+TtgCcK0qoF61rz0NfK6pZazrqLZ2hWrXTAv7IKotnvmxFV0\r\niPvD98eFEfFh4nm/uAb8yxTVBjJo6ypw/Gi5P5LLac3R4Hth7P6ILpCXtiJV\r\nTGttPGLvH93IwGiIfP9Rudv2mUAq2Oyg1fNyIhCtyYfg8f9ugN26ezUTljf2\r\nQqrSuOIMAJWByZinXEEfTLOz9v9fZfWQ80H/S9hc54xqqcpDIO/dPYXJo56n\r\ndEnL3PhrwwB1bPZ+XN0pcvbNWLsTpolca+FzstbEguMRTLrYudUc8cfhvNGx\r\n1/el3KO4vXAcTn52w96rkVpPDdJpA+A2N9+FBbQvqVeyPx+PAX0zhDLMCAe5\r\nB3TTTM4pWutoD5w5Lt6+Y8nmn+DcxjI0m8MMy2qohT2p5zy51htiFspqoX8x\r\ndsPS6HgWX+JzLFE/GNTzbHLTQ1Hhnxnv8KfeOodC+K7nQMsfvr+7J54gJ0Yd\r\nE87BhWNJJh0A6QsLbmwsR0FPH4ppJDxf43iGrIZeVHVvL3XNJZwb0oUUQayN\r\nh6/QmKfN57/oqwhrrKGxedhrc9BzZFjkY90dE/FZb5r8LJudmnNtblfAZvrc\r\nf8CmcXor+YwX2Qq9zwHP7BYzrIDjOfrTcj0=\r\n=VDhx\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.9453780_1669125983093_0.9667525209883066"},"_hasShrinkwrap":false},"7.2.10180649":{"name":"@metrichor/epi2me-api","version":"7.2.10180649","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"30b242611a234cfb8a8b10e1c6152823ae1668e4","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.10180649","_nodeVersion":"16.19.1","_npmVersion":"8.19.3","dist":{"integrity":"sha512-Y//k2ZEWSoTtpUoYo073dNWwp2Dwd/aQGbqz7HB1c4QbjUOtclQC8lwINP6JSt4oxgHzzqQXeVoV2bvBfqzdew==","shasum":"42960d95a8cd5d800ea1a213c38fd18769a76f9e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.10180649.tgz","fileCount":319,"unpackedSize":611045,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHL9/hqEh6y8dAeYGli8deS2SYD8L6kM1NxF/fG7qx7FAiAY5HNy3uZV1sVMIc19hOcf6xHosz9kplKh2AWE4h2vlg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj/i77ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrIRxAAmjMdc0oxicorJXgYBBqOl3o3XpKbUY33yiX4bkENu6M0otWX\r\nBtXB+yqJg5N5yuMSVuSekf5JFN+beDnRQlKL+giW3TL71qF2IyPrbKhsuLcl\r\nyYadGys/hj5p2vANgrSHdD0DQFRUW9v3zHebvVzP5TIWn1lfUtu119Wj1HaK\r\nr10awjORf/7V/76EZL0zSc5SVli1mM6pZBYG2UN4Rfyh43lYinDcdc2skkjO\r\nQUxYEmaAnWYkubd7cS+Z6eGozU7R9Evr6kqkzS8dnvyruEzkwDRmtHSe092m\r\nFRNNyyKX9NJCaeqno6jT9Hl69b4VfuqAkVM/zKNIxNebOG4uchF9gP1gymW+\r\n+3tXj8oN2WbAZcL4CYGuAY+JQMRMwOLX7DMeMB5K3QdSnBt+UsoNCtMRqQJG\r\nO4sacfv4COHlMZt9aFdgaFZBKyMudjcnFejsA254hldEwJbfnADeO5I15FpJ\r\nzi9rMeF1KAkipXTYlaelthRW9nMwqzaG+crh7Q3lsODr0wuy/YRFuyP59GXI\r\nWBW11wb/z2IDakZPC6I60UlF3X+sf5233FNkGxWChBGLqWwOOGq1aZmYkhjV\r\nBtWONN2tm67BZ6g9BN7kAUkhs5BnWokvlDNEkWJo4JR2NhEwVZzIU/tDuZO5\r\nApd6Lssnxqfd4MwY0+sohGhJ/c+nyuwhem4=\r\n=Wo3Q\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.10180649_1677602555636_0.2013844891312413"},"_hasShrinkwrap":false},"7.2.10218934":{"name":"@metrichor/epi2me-api","version":"7.2.10218934","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","aws-sdk":"^2.1002.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"5fddfbb8e1ed772ab5b97cd27837d6bc13e83e28","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.10218934","_nodeVersion":"16.19.1","_npmVersion":"8.19.3","dist":{"integrity":"sha512-kGly2YOd0QX03JjUC4WTKO3CxKHlmgkPn1ECT8Rk7nXVEzAaXbR2qro3HAvoPj94gUKhqLjOJpZRwdCxVFRQZw==","shasum":"aca5341b785acd81d4c6e91a1661859833e73107","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.10218934.tgz","fileCount":319,"unpackedSize":611045,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC8fDoirg6MVR3hJUX7zzcrA7dZP2H84XkHzce4wY/7PQIgMgg2IanM+jEpYn3Ns/P6Mp3G3oz5AZl37hEzq3I/dzc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkAfGkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrYlw//bnqVQAxu1u3hu/hLENy0g5QYs9Fu+Dw5FTCuG/Nt41gn7IBV\r\nksfWRoWxaPECHMREkrr1kenyO2CarDacFTDFyJA6yGC0XbjeuGf8SBtyfc1Z\r\narYzUGIhevd4mP2IJTnKi4PhkvK5yYB3zxL7C3eLW3u0YYFh9KRI8Yl3ixwJ\r\nIeDelj9bwDOCuyKlPoD5Ik4/M7zjWJenw3FLubUhd/ZLTbseqQBjsUmbQ740\r\nynFZ/oYkaXElBJ72NeBHrBJdGfxOHpEHPVB0pM3CS6eZyXoaDGwHKtHfjoYL\r\nnQgrciG0VYPxvdJ483hOPWfqx2uYB2etv5h4jKEwL1H9+V8VIJedQ4GCwzuk\r\nHv2ECsCy9gWWV3P/qFGswBz00Fyj/VnXDyHFqNcAsxamwjG0tKmEPv5UXyjd\r\nbPF5a7Nv1fDBKGsMkVbTx/xBcy9Kc3VnFR9QLHnemyGxV6n4Jlh9dHVIiK0B\r\nssG9YOHz/PAEQaWxYApNSVhFLC1QZ72xj+fT1y6D1nO5ML70K1i5Nj1l9adQ\r\nMZl2URW+ya6SDCLOnVYe8Xeq2zoJFAgyBpISCOhUZbstFhc5JaaIi5TY7mol\r\n+y6KsRvYHs5HtUIZh+9/RSL4ODx8ww8y4kxrBeqXWc77nKcoLOYYkPLgvFYP\r\nlKZIZKa1BP7bE4Tq5ROIcTMb0hy3IEXCDP0=\r\n=wcDb\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.10218934_1677848996751_0.3701463182821112"},"_hasShrinkwrap":false},"7.2.10393877":{"name":"@metrichor/epi2me-api","version":"7.2.10393877","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","agent-base":"^6.0.2","aws-sdk":"^2.1002.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"92bc22d9a4aa3068a1bc40a423b86c0b4ca39dff","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.10393877","_nodeVersion":"16.19.1","_npmVersion":"8.19.3","dist":{"integrity":"sha512-5DIGn0t+eMgKuVXcilC83g28EbPNn6sSjFy53BmRnClRPbYmdrRskIcpdzyMtwA10+kbRFfBh8bXrFY7gNG+uw==","shasum":"2330c0a9e40e202751865c0c6d146dbcf74adfa2","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.10393877.tgz","fileCount":319,"unpackedSize":612178,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD/SonEKUoWzLKU7TUY4Hz+A0UPADU/V81ErwfEaZO56gIgMopOELbX3RGXWbEk3Go0awye1fAJ3byHWhw7/r7wsS4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGfw7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrsXg//cbj+I4fuX4p684gT0JVOuqU59tdPTtXAJZR3UJN2E3JOE3qD\r\n8PrEMY9UJU9NnjKUI8NmsyUNTIEAQyjwb8RMheApC80dyh0uKvSb3QYiA/Ki\r\nCUH58WHXPXTKIY/iK9lmxqPQWEexrSjAdIUko+tRR+oN41f342vjX26KOfux\r\nFUN5rFZda4qRpq2okWF+mQkdi3+/4x2RxmRu3p+uRXAl2qXIcy1BB7fl8vso\r\n68GCYWRh6WZN6hEYdw4TW7cvA67xy/3xR32k4Os9q5t2kcS9IEqA/byEuD71\r\nkGDz/k/weTHb0ZRb/xqx9UcLyGmYVn+YsewpxAavoN8t993Cc2+DNYOUDsUe\r\nF54VYyYVta0XxKBl1wb2vVCxq+44AfaHUx0vuSCaxPoLq1suEQtjXyV9YITM\r\nVwSxXq3lkuBFTmeIUK6f00Iw9kd/vz+GEevDRNLiOmNoEP+bVR667H1qwgUO\r\nlECrCtBubJuZ3ej3sBQ1aZBm/14qGmLq2eNXAXnwpsA1G27n7byyJYh3eAaO\r\ngFfq6cw28lCgKwPiWdCXVOidPAlXFuumqkG6TZvREXIjFyl8iffunAlkm16v\r\nidGQdmqLxcfnB3w8WRoX+G7fnIQGccq8ofdrWzlAVXUl1jV07eFl6OCUjkTb\r\nfAYFtz2QUMfDrrAOOSAmUF/10nrrIxfWa9Q=\r\n=WxTH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.10393877_1679424571409_0.6012963956189761"},"_hasShrinkwrap":false},"7.2.10405862":{"name":"@metrichor/epi2me-api","version":"7.2.10405862","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.4.16","@types/socket.io-client":"^3.0.0","agent-base":"^6.0.2","aws-sdk":"^2.1002.0","cross-fetch":"^3.1.5","fs-extra":"^10.0.0","fs-inspect":"^1.0.5","graphql":"^15.6.1","graphql-tag":"^2.12.5","https-proxy-agent":"^5.0.1","immutable":"^4.0.0-rc.15","pac-proxy-agent":"^5.0.0","rxjs":"^7.4.0","socket.io-client":"^4.4.1","socks-proxy-agent":"^7.0.0","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"f003115843bcccfaeb1e5056810ef168ad151d68","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.10405862","_nodeVersion":"16.19.1","_npmVersion":"8.19.3","dist":{"integrity":"sha512-JQs5tY1QrtmJ43cbzX8cqKVEsqDOtYXTYkrfolM/D6VAO/jWSlXULwaO1B55pHRrJ5b+1Unl1YDIa4WpaYrx0A==","shasum":"f1feff39755d543a3bd6a4dbe3058c30a2add4ba","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.10405862.tgz","fileCount":319,"unpackedSize":612178,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID9CdOpM/BmDdeG6qAqKCIu0oKQNxtNscUmMtTCSoNzpAiBaecvZtYBrR7ziedjL9QIzeLc45viGDS2+Lyf8F+8FHQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkG0NWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpBhw//ZH1mGNCOq5a/Rwlleh0P+wgPPlMKLYzTFSM9Rbk43NS29z5D\r\nLfs1OaNP2go34QSAvtqbGaj7lGBBNp0lurgovMjYlKFNTAKgNt5nFTLIHgRs\r\n57yQx1t1s+QagavevDWCvB4dpGu2g73cHlN9yOZdV6dGn/iEXG/c4wj3/tJw\r\nQs8w568pgviqGSr5Zab+aM9RVqFkFIfHnJfy2DNXqKtsIlKK49W0DNI9xxgZ\r\nvbtJR1hpEuanTZzdUdEYECMtT5Fy9vFXSQ+DLGyl3i0CIorbMc5wA9w+k92s\r\nPgSHoHNSJ+DvZeDW4Fu3H1wE/eqfIRIv495xOSp+aMaeCi9/a8mNOaOrtXgO\r\nipcqIr10lykPi+IiA8m/v8syo15tPdXFR3temdahSaqi8SQLRoH/5g6O1kYm\r\nlC1Fp6VkaWXaHd2ghTgeLUg/gpHO36Zypvr8FdClgyKn9Vnj1VBkjwMmVV07\r\n5LakEPBtvMziXsKzIqRhEtzbGxkzK214QWCYdLMlEjNNyCXVG8TRLah/3+MQ\r\n2qeYE4Y3naBqPsEE+0rFbqg2FcgwMTww3sO/VnqR9IBhEKnweSadCcEo2IwZ\r\n3WBKMfBiQPwNlZYp3hD1oxxDrBCzebNG3lrPZGWuvn/mAt8XTnamtulgd0WQ\r\nsCCyEQfu6Jgc3N8/PPvVtWuCAj06pQxHFck=\r\n=3iIs\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.10405862_1679508309940_0.030947175847289232"},"_hasShrinkwrap":false},"7.2.11907093":{"name":"@metrichor/epi2me-api","version":"7.2.11907093","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.7.17","@types/socket.io-client":"^3.0.0","agent-base":"^7.1.0","aws-sdk":"^2.1418.0","cross-fetch":"^4.0.0","fs-inspect":"^1.0.5","graphql-tag":"^2.12.6","https-proxy-agent":"^7.0.1","immutable":"^4.3.1","pac-proxy-agent":"^7.0.0","rxjs":"^7.8.1","socket.io-client":"^4.7.1","socks-proxy-agent":"^8.0.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"1208aa7c16e7f78f6944963bceec6002b186ba67","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.2.11907093","_nodeVersion":"16.20.1","_npmVersion":"8.19.4","dist":{"integrity":"sha512-MW5/4j6xGWNNRGfmu7CPW194B2CnWgjFPK40Y4qXMDdLqrm0mCoPU17wXbqaF0Diogqvr3O8OJh5Lt3G2tmfAg==","shasum":"03230940c7330de754120eb49d8b298fd6d6b7cb","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.2.11907093.tgz","fileCount":319,"unpackedSize":607094,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFmKetPBUODsg/qzaXvLeZJQH5ZF1auMc32gla/StscWAiEAi+oMjQ2pMutkQf9eUj9k/7ZJ+ESaNPLpUEFCgQQ70ws="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.2.11907093_1690278566520_0.8047494631452052"},"_hasShrinkwrap":false},"7.3.11924383":{"name":"@metrichor/epi2me-api","version":"7.3.11924383","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.7.17","@types/socket.io-client":"^3.0.0","agent-base":"^7.1.0","aws-sdk":"^2.1418.0","cross-fetch":"^4.0.0","fs-inspect":"^1.0.5","graphql-tag":"^2.12.6","https-proxy-agent":"^7.0.1","immutable":"^4.3.1","pac-proxy-agent":"^7.0.0","rxjs":"^7.8.1","socket.io-client":"^4.7.1","socks-proxy-agent":"^8.0.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"d6bd3100b3a4ca03c1e1151f74e9cc6510527b96","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.3.11924383","_nodeVersion":"16.20.1","_npmVersion":"8.19.4","dist":{"integrity":"sha512-B5uVm3CmE68VDjF4YQcq+z82DwPKN9ArVYdZDmKaxE/cNt1s/kNcqk9G8a9fMDqbb4QCfaBJTfVluNyfBM3PWQ==","shasum":"5acbcbf6e9ad8a91cb2fe9bce9f32e641dc179c4","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.3.11924383.tgz","fileCount":319,"unpackedSize":607094,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC1h+10zQ41p4cz7dwg0Y/LuzyOjq0t7lMUL4iRc2D4DAiEA/hhGeTVtOOwhLIOTygDDVclzxanZBgSxMdXQg34HKHE="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.3.11924383_1690369012516_0.1127596638677899"},"_hasShrinkwrap":false},"7.3.11924827":{"name":"@metrichor/epi2me-api","version":"7.3.11924827","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.7.17","@types/socket.io-client":"^3.0.0","agent-base":"^7.1.0","aws-sdk":"^2.1418.0","cross-fetch":"^4.0.0","fs-inspect":"^1.0.5","graphql-tag":"^2.12.6","https-proxy-agent":"^7.0.1","immutable":"^4.3.1","pac-proxy-agent":"^7.0.0","rxjs":"^7.8.1","socket.io-client":"^4.7.1","socks-proxy-agent":"^8.0.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"328f4d3484734fad0009c53b32cf4686b4024548","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.3.11924827","_nodeVersion":"16.20.1","_npmVersion":"8.19.4","dist":{"integrity":"sha512-yJYaT3et+Km8tOo0JGgPj99RG3uI2AL7+spdGA0SNFSxjt1Bd1fo9Gj47uzYtCiqVl8QgJgg8CCUQ0BvhFklAA==","shasum":"4236ba5ba53d1440a63ae6e54d7b1b2f0684f26e","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.3.11924827.tgz","fileCount":319,"unpackedSize":607094,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBlwi1aPWgzpbcVnxXRB0tpE2OX+RI0HzyZREFXKI47IAiEA9GtJzoW0s21Nca6E+v2TeYzi8Zu1zTmqOy8sr14JlXw="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.3.11924827_1690370368263_0.6838069093904431"},"_hasShrinkwrap":false},"7.3.11957764":{"name":"@metrichor/epi2me-api","version":"7.3.11957764","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.7.17","@types/socket.io-client":"^3.0.0","agent-base":"^7.1.0","aws-sdk":"^2.1418.0","cross-fetch":"^4.0.0","fs-inspect":"^1.0.5","graphql-tag":"^2.12.6","https-proxy-agent":"^7.0.1","immutable":"^4.3.1","pac-proxy-agent":"^7.0.0","rxjs":"^7.8.1","socket.io-client":"^4.7.1","socks-proxy-agent":"^8.0.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"8da4e978164adfd99aae86836a257b58c6f51e4c","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.3.11957764","_nodeVersion":"16.20.1","_npmVersion":"8.19.4","dist":{"integrity":"sha512-EfDMWfvgAJvKWFJdN4eMx/S3Z6xycDtkDMfM4l6Ujp63LfGnoc1eJeXrj7sl4FwcLj9Zn4YqahWIUhAbTInAKA==","shasum":"96c76ff0ad7ad4037d4e35d68588fbe3cfe526f2","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.3.11957764.tgz","fileCount":319,"unpackedSize":592754,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGXeaa1giiq0NzRk94ZilddDSDqFykbCDq3CQpLjTuh+AiAncuiqt9fbj21svcYjfkLq3O3WtHk1UDb61SXi2Z/FrQ=="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.3.11957764_1690475600312_0.29300799183874426"},"_hasShrinkwrap":false},"7.3.11957861":{"name":"@metrichor/epi2me-api","version":"7.3.11957861","license":"MPL-2.0","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"description":"API for communicating with the EPI2ME website(s)","author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"},"main":"cjs/src/index.js","module":"mjs/src/index.mjs","types":"mjs/src/index.d.ts","dependencies":{"@apollo/client":"^3.7.17","@types/socket.io-client":"^3.0.0","agent-base":"^7.1.0","aws-sdk":"^2.1418.0","cross-fetch":"^4.0.0","fs-inspect":"^1.0.5","graphql-tag":"^2.12.6","https-proxy-agent":"^7.0.1","immutable":"^4.3.1","pac-proxy-agent":"^7.0.0","rxjs":"^7.8.1","socket.io-client":"^4.7.1","socks-proxy-agent":"^8.0.1","ts-runtime-typecheck":"^2.6.0"},"readme":"# EPI2ME API\n\n<a href=\"http://metrichor.com\"><img src=\"https://epi2me.nanoporetech.com/gfx/logo_print.png\" height=\"74\" alt=\"A stylised letter E made of 3 coloured horizontal bars followed by the word EPI2ME. The colours are turquoise, yellow and blue.\" align=\"right\"></a>\n\nThis API provides utilities for communicating with the EPI2ME Platform for the analysis of nanopore data. It is used by the EPI2ME Agent & CLI. It is intended to be used with Node.js. More information on the EPI2ME platform can be found at [metrichor.com](https://metrichor.com/).\n\n## Installation\n\n```sh\nnpm i @metrichor/epi2me-api\n```\n\nIn addition to the main module a \"web\" variant exists which can work in a browser. It is limited to the GraphQL API, and does not expose any methods for reading files from disk. Additionally the GraphQL client is limited to JWT based authentication.\n\n```sh\nnpm i @metrichor/epi2me-web\n```\n\n## GraphQL API\n\nThe EPI2ME service is implemented as a GraphQL API. This provides a great amount of flexibility with what data you want to request, and as a bonus provides amazing TypeScript support via graphql-codegen.\n\nNormally GraphQL is intended to be used with situation specific queries, not generalized ones. However, we do provide some general purpose version of standard queries. You may find that you can get more relevant information by writing your own query, or that a custom query takes less time to complete. So it's advised to consider what fields you actually want and write your own query. But the inbuilt queries offer convenience during the prototyping stage of a project.\n\n### Authentication, GraphQL clients and context\n\nOur GraphQL service requires authentication. This can be provided either by using a JWT or a API key/secret pair.\n\nTo create an authenticated connection using an API key/secret pair instantiate a GraphQLFS instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nconst client = new GraphQLFS({\n  apikey,\n  apisecret,\n});\n```\n\nThe constructor accepts some other options, such as the `url` of the environment and a `proxy` configuration string. But `apikey`/`apisecret` are the only required ones. The new client instance encapsulates the authenticated connection to the GraphQL server, allowing you to perform queries and mutations.\n\nThis client object exposes `query` and `mutate` methods that accept a document and variables and perform the request. It is advised to generate documents ahead of time using graphql-codegen, as when used in conjunction with the schema it will validate your queries. However, you can also generate documents at runtime using the graphql tag library. In addition to `query` and `mutate` the client also defines `wrapQuery` and `wrapMutation` methods which allow for partial application of a document to `query` and `mutate` respectively. A number of inbuilt queries and mutations are also defined for common operations.\n\n- `workflows` list available workflows in the current region; this query is paginated.\n- `workflow` get details for a specific workflow using a workflow ID.\n- `workflowInstance` get details for a specific workflow instance using a workflow instance ID.\n- `workflowInstances` list workflow instances in the current region; this query is paginated.\n- `startWorkflow` instantiate a workflow in the current region with workflow ID and a set of parameters. Will return details of the workflow instance.\n- `stopWorkflow` stop a workflow instance with a given workflow instance ID.\n- `instanceToken` create an instance token for accessing the S3 bucket and SQS queue belonging to a workflow instance.\n- `user` get details about the current user.\n- `updateUser` change the preferred region of the current user.\n- `regions` list available regions.\n\n## Running a workflow\n\nThe primary use for the EPI2ME API is to run workflows. In the case you are starting a workflow from an existing dataset, and only wish to view the resulting report then it should be sufficient to construct a GraphQL client and make a startWorkflow mutation. This will not allow you to upload files or (easily) monitor the state of the workflow instance.\n\n```ts\nimport { GraphQLFS } from '@metrichor/epi2me-api';\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const client = new GraphQLFS({ apikey, apisecret });\n\n  const { instance } = await client.startWorkflow({\n    computeAccountId,\n    isConsentedHuman,\n    idWorkflow: '<ID of the workflow to run>',\n    idDataset: '<ID of source dataset>'\n  });\n\n  console.log(`Started workflow instance ${instance.idWorkflowInstance}`)\n}\n\n```\n\nA more comprehensive option is instantiate an `EPI2ME` instance. This will encapsulate a GraphQL client, file scanner/uploader, telemetry monitoring and observe the status of the attached workflow instance.\n\n```ts\n\nimport { EPI2ME, Profile } from '@metrichor/epi2me-api'\n\nasync function main (profile: Profile, isConsentedHuman: boolean) {\n  const { apikey, apisecret, compute_account: computeAccountId } = profile;\n\n  const epi2me = new EPI2ME({\n    apikey,\n    apisecret,\n    inputFolders: [\n      '<folder path for files to upload>'\n    ],\n    outputFolder: '<folder path for files to download>'\n    useGraphQL: true, // for compatibility the instance currently defaults to REST mode, but we are in the process of deprecating our REST backend\n  });\n\n  // autoStartGQL accepts the same parameters as GraphQL.prototype.startWorkflow\n  await epi2me.autoStartGQL({\n    isConsentedHuman,\n    computeAccountId,\n    idWorkflow: '<ID of the workflow you want to run>',\n  });\n\n  console.log(`Started workflow instance ${epi2me.id}`)\n\n  // observe the report state and signal when the report is ready\n  epi2me.reportState$.subscribe(isReady => {\n    if (isReady) {\n      console.log('Report is ready!')\n    }\n  })\n}\n\n```\n\n## Profiles\n\nWhen using EPI2ME applications they can register a profile for a given user. This stores the authentication required to utilise that user on the device. You can read and modify profiles on the current device using the profile manager.\n\n```ts\nimport { instantiateProfileManager } from '@metrichor/epi2me-api'\n\nasync function main () {\n  const { manager } = await instantiateProfileManager();\n\n  const names = Array.from(manager.profileNames());\n  \n  const firstProfile = manager.get(names[0]);\n\n  console.log(`The apikey for the profile ${names[0]} is ${firstProfile.apikey}`)\n}\n```\n\nProfiles can also hold an `endpoint` as well as `compute_account` value. The account value in particular can be very helpful as it means you don't have to query a list of accounts for a user and pick one. It is however worth noting that all of the field of a profile are _optional_ so you should check they exist before attempting to utilise the profile.\n\nEPI2ME applications do not monitor profiles for changes on disk, so if you change any profiles any active application will have to be restarted before it will observe any changes. Any changes made to profiles by EPI2ME applications will be immediately be written to disk, so it's best to avoid modifying the profile list in multiple processes at once otherwise you risk race conditions.\n\n## Instance lifecycle\n\nOnce an EPI2ME instance has been created it triggers several services that run for the duration of the instance.\n\n### File Uploader\n\nThe specified input folders are scanned on an interval for new files. If the files fulfil the criteria of the uploader ( not yet uploaded and correct file type ) then they are concurrently uploaded. After each file is uploaded a message is send to the backend to indicate that there is new data available.\n\nIf you are running off static data you will probably not want to continue scanning for new files once all your files have been uploaded. You can monitor the status of the file uploads using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\nTo stop the file uploaded call `stopUpload()`. This will not stop the analysis of the data, or the download of results.\n\n### Telemetry\n\nYou can process the telemetry of the workflow in real time by utilizing `instanceTelemetry$` which is an observable containing the JSON blobs from each workflow component in the chain. Changes in this data are received through polling, updated telemetry is only pulled down if a change has occurred though.\n\n### Output Data\n\nOnce data has passed through the workflow the client is notified of result data, which can then optionally be downloaded to the client. Setting the `downloadMode` to `data` or `data+telemetry` will cause the output to be downloaded and written to disk. The progress of downloads can be observed using `liveStates$` which is an observable that contains statistics about uploaded and downloaded files.\n\n### Stopping an Analysis\n\nAs analyses are designed to receive new data as it's being generated they do not have a classical \"complete\" state. They rather have a \"analyzing\" and \"idle\" state, once all the uploaded data has been processed they will sit idle waiting for more data. Once you are happy that all of your data has been processed you need to notify the system that you have finished and stop the analysis. You can remotely stop any running workflow from the EPI2ME agent and portal easily. Through the API you can either use the `stopWorkflow` mutation to stop your workflow, or if you have instantiated an EPI2ME instance you can call `stopAnalysis`.\n\n## Datasets\n\nEach component in a workflow instance creates it's own \"dataset\". By default datasets are deleted within 24 hours of an analysis being stopped, but if you pass in the `storeResults` flag when starting the workflow they will be persisted. Alternatively you can view the dataset on the EPI2ME portal while the analysis is being run and set specific datasets to be persisted.\n\nDatasets give you the means to run a workflow from data which you have already uploaded and/or processed. EPI2ME will also keep track of the relationship between your datasets, so that you can easily track the source of particular data. You can also download a dataset at a later date.\n\nYou can start workflows from dataset using the start workflow mutation by specifying a dataset ID in it's parameters. It's also possible to start a workflow from a dataset using the EPI2ME portal and CLI.\n\n## Development\n\nThe EPI2ME API is under constant refinement based on the requirements and capabilities of the system. We are currently in the process of migrating from a REST based backend to a newer GraphQL one. For compatibility we are supporting both for the time being, but once internal projects have migrated away from the old REST API those components will be removed facilitating further simplification and improvement to this library.\n\n## Depreciation\n\nWe are depreciating the old REST api systems soon in favour of our GraphQL backend. These changes are reflected in the removal/replacement of these systems in our dev branch. Migration is intended to be feature complete, but there will be some slight change to how you access certain content. If it's not clear from the documentation please create an issue so that it can be correctly documented, or implemented if we missed something.\n","readmeFilename":"README.md","gitHead":"25ad947b22c227333d55081915a75e9de0498b4c","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"homepage":"https://github.com/nanoporetech/epi2me-api#readme","_id":"@metrichor/epi2me-api@7.3.11957861","_nodeVersion":"16.20.1","_npmVersion":"8.19.4","dist":{"integrity":"sha512-ApbNmo5Wz8Jbt9rIgmYdEESDTGKgL6CPdhWgOA49lX3xVcSjD/FJFm1GnVkaHZplhbwR5U0yYi1bIdrF5MOR8A==","shasum":"e57bb0b3f7e59a0db050607946e848645b6f6b03","tarball":"https://registry.npmjs.org/@metrichor/epi2me-api/-/epi2me-api-7.3.11957861.tgz","fileCount":319,"unpackedSize":592754,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDVKXRMHBVWpYbVa8IyaDTlRSRI9pnHXUIoaspOBHCgeAiEA906OO6hEAdYicCiSiuRStDNQcwauZwj1wE/Gh/d4vV4="}]},"_npmUser":{"name":"mcbot","email":"roger.pettett@metrichor.com"},"directories":{},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/epi2me-api_7.3.11957861_1690475807666_0.1697396080913356"},"_hasShrinkwrap":false}},"maintainers":[{"name":"shortercode","email":"iainshorter@gmail.com"},{"name":"rmp","email":"rmp@psyphi.net"},{"name":"glenveegee","email":"glenveegee@gmail.com"},{"name":"mcbot","email":"roger.pettett@metrichor.com"}],"description":"API for communicating with the EPI2ME website(s)","repository":{"type":"git","url":"git+ssh://git@github.com/nanoporetech/epi2me-api.git"},"license":"MPL-2.0","readme":"","readmeFilename":"","homepage":"https://github.com/nanoporetech/epi2me-api#readme","bugs":{"url":"https://github.com/nanoporetech/epi2me-api/issues"},"author":{"name":"Oxford Nanopore Technologies","email":"support@nanoporetech.com","url":"https://nanoporetech.com"}}