├── .babelrc
├── .gitattributes
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── .idea
├── .gitignore
├── codeStyles
│ └── codeStyleConfig.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── js-coroutines.iml
├── misc.xml
├── modules.xml
└── vcs.xml
├── .prettierrc
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENCE.txt
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── _config.yml
├── dist
├── append-async.js
├── append.js
├── array-utilities.js
├── async-array-wrappers.js
├── async-compression-wrappers.js
├── async-json-wrappers.js
├── async-wrapper-utils.js
├── async-wrappers.js
├── branch.js
├── call.js
├── compose.js
├── concat-async.js
├── concat.js
├── coroutines.js
├── es6
│ ├── append-async.js
│ ├── append.js
│ ├── array-utilities.js
│ ├── async-array-wrappers.js
│ ├── async-compression-wrappers.js
│ ├── async-json-wrappers.js
│ ├── async-wrapper-utils.js
│ ├── async-wrappers.js
│ ├── branch.js
│ ├── call.js
│ ├── compose.js
│ ├── concat-async.js
│ ├── concat.js
│ ├── coroutines.js
│ ├── every.js
│ ├── filter-async.js
│ ├── filter.js
│ ├── find-async.js
│ ├── find-index-async.js
│ ├── find-index.js
│ ├── find.js
│ ├── for-each-async.js
│ ├── for-each.js
│ ├── group-by-async.js
│ ├── group-by.js
│ ├── includes-async.js
│ ├── includes.js
│ ├── index-of-async.js
│ ├── index-of.js
│ ├── index.js
│ ├── is-object.js
│ ├── jscoroutines.d.ts
│ ├── json.js
│ ├── key-by-async.js
│ ├── key-by.js
│ ├── last-index-of-async.js
│ ├── last-index-of.js
│ ├── lz-string
│ │ ├── base64-string.js
│ │ └── lz-string.js
│ ├── map-async.js
│ ├── map.js
│ ├── pipe.js
│ ├── polyfill.js
│ ├── reduce-async.js
│ ├── reduce.js
│ ├── repeat.js
│ ├── run.js
│ ├── singleton.js
│ ├── some-async.js
│ ├── some.js
│ ├── sort-async.js
│ ├── tap.js
│ ├── timsort.js
│ ├── unique-by-async.js
│ ├── unique-by.js
│ ├── update.js
│ ├── useInternalEngine.js
│ ├── wrappers.js
│ └── yastjson
│ │ └── lib
│ │ ├── ast.js
│ │ ├── expression.js
│ │ ├── parse.js
│ │ ├── token.js
│ │ ├── tokenizer.js
│ │ └── yielder.js
├── every.js
├── filter-async.js
├── filter.js
├── find-async.js
├── find-index-async.js
├── find-index.js
├── find.js
├── for-each-async.js
├── for-each.js
├── group-by-async.js
├── group-by.js
├── includes-async.js
├── includes.js
├── index-of-async.js
├── index-of.js
├── index.js
├── is-object.js
├── json.js
├── key-by-async.js
├── key-by.js
├── last-index-of-async.js
├── last-index-of.js
├── lz-string
│ ├── base64-string.js
│ └── lz-string.js
├── map-async.js
├── map.js
├── pipe.js
├── polyfill.js
├── reduce-async.js
├── reduce.js
├── repeat.js
├── run.js
├── singleton.js
├── some-async.js
├── some.js
├── sort-async.js
├── tap.js
├── timsort.js
├── unique-by-async.js
├── unique-by.js
├── update.js
├── useInternalEngine.js
├── wrappers.js
└── yastjson
│ └── lib
│ ├── ast.js
│ ├── expression.js
│ ├── parse.js
│ ├── token.js
│ ├── tokenizer.js
│ └── yielder.js
├── doc.conf.json
├── docs
├── Iterator.html
├── array-utilities.js.html
├── async-wrappers.js.html
├── coroutines.js.html
├── fonts
│ ├── Montserrat
│ │ ├── Montserrat-Bold.eot
│ │ ├── Montserrat-Bold.ttf
│ │ ├── Montserrat-Bold.woff
│ │ ├── Montserrat-Bold.woff2
│ │ ├── Montserrat-Regular.eot
│ │ ├── Montserrat-Regular.ttf
│ │ ├── Montserrat-Regular.woff
│ │ └── Montserrat-Regular.woff2
│ └── Source-Sans-Pro
│ │ ├── sourcesanspro-light-webfont.eot
│ │ ├── sourcesanspro-light-webfont.svg
│ │ ├── sourcesanspro-light-webfont.ttf
│ │ ├── sourcesanspro-light-webfont.woff
│ │ ├── sourcesanspro-light-webfont.woff2
│ │ ├── sourcesanspro-regular-webfont.eot
│ │ ├── sourcesanspro-regular-webfont.svg
│ │ ├── sourcesanspro-regular-webfont.ttf
│ │ ├── sourcesanspro-regular-webfont.woff
│ │ └── sourcesanspro-regular-webfont.woff2
├── global.html
├── index.html
├── scripts
│ ├── collapse.js
│ ├── linenumber.js
│ ├── nav.js
│ ├── polyfill.js
│ ├── prettify
│ │ ├── Apache-License-2.0.txt
│ │ ├── lang-css.js
│ │ └── prettify.js
│ └── search.js
├── styles
│ ├── jsdoc.css
│ └── prettify.css
└── wrappers.js.html
├── mocha.wallaby.js
├── out
└── types.d.ts
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── scripts
└── build.sh
├── src
├── App.css
├── App.js
├── App.test.js
├── component
│ ├── append-async.js
│ ├── append.js
│ ├── array-utilities.js
│ ├── async-array-wrappers.js
│ ├── async-compression-wrappers.js
│ ├── async-json-wrappers.js
│ ├── async-wrapper-utils.js
│ ├── async-wrappers.js
│ ├── branch.js
│ ├── call.js
│ ├── compose.js
│ ├── concat-async.js
│ ├── concat.js
│ ├── coroutines.js
│ ├── every.js
│ ├── filter-async.js
│ ├── filter.js
│ ├── find-async.js
│ ├── find-index-async.js
│ ├── find-index.js
│ ├── find.js
│ ├── for-each-async.js
│ ├── for-each.js
│ ├── group-by-async.js
│ ├── group-by.js
│ ├── includes-async.js
│ ├── includes.js
│ ├── index-of-async.js
│ ├── index-of.js
│ ├── index.js
│ ├── is-object.js
│ ├── jscoroutines.d.ts
│ ├── json.js
│ ├── key-by-async.js
│ ├── key-by.js
│ ├── last-index-of-async.js
│ ├── last-index-of.js
│ ├── lz-string
│ │ ├── base64-string.js
│ │ └── lz-string.js
│ ├── map-async.js
│ ├── map.js
│ ├── pipe.js
│ ├── polyfill.js
│ ├── reduce-async.js
│ ├── reduce.js
│ ├── repeat.js
│ ├── run.js
│ ├── singleton.js
│ ├── some-async.js
│ ├── some.js
│ ├── sort-async.js
│ ├── tap.js
│ ├── timsort.js
│ ├── unique-by-async.js
│ ├── unique-by.js
│ ├── update.js
│ ├── useInternalEngine.js
│ ├── wrappers.js
│ └── yastjson
│ │ ├── lib
│ │ ├── ast.js
│ │ ├── expression.js
│ │ ├── parse.js
│ │ ├── token.js
│ │ ├── tokenizer.js
│ │ └── yielder.js
│ │ └── test
│ │ └── test.json
├── index.css
├── index.js
├── logo.svg
├── serviceWorker.js
├── setupTests.js
└── test
│ ├── array-async.test.js
│ ├── array-generator.test.js
│ ├── basic-express.js
│ ├── compression.test.js
│ ├── functional.test.js
│ ├── json.test.js
│ └── sort.test.js
└── template
├── LICENSE
├── publish.js
├── static
├── fonts
│ ├── OpenSans-Bold-webfont.eot
│ ├── OpenSans-Bold-webfont.svg
│ ├── OpenSans-Bold-webfont.woff
│ ├── OpenSans-BoldItalic-webfont.eot
│ ├── OpenSans-BoldItalic-webfont.svg
│ ├── OpenSans-BoldItalic-webfont.woff
│ ├── OpenSans-Italic-webfont.eot
│ ├── OpenSans-Italic-webfont.svg
│ ├── OpenSans-Italic-webfont.woff
│ ├── OpenSans-Light-webfont.eot
│ ├── OpenSans-Light-webfont.svg
│ ├── OpenSans-Light-webfont.woff
│ ├── OpenSans-LightItalic-webfont.eot
│ ├── OpenSans-LightItalic-webfont.svg
│ ├── OpenSans-LightItalic-webfont.woff
│ ├── OpenSans-Regular-webfont.eot
│ ├── OpenSans-Regular-webfont.svg
│ ├── OpenSans-Regular-webfont.woff
│ ├── OpenSans-Semibold-webfont.eot
│ ├── OpenSans-Semibold-webfont.svg
│ ├── OpenSans-Semibold-webfont.ttf
│ ├── OpenSans-Semibold-webfont.woff
│ ├── OpenSans-SemiboldItalic-webfont.eot
│ ├── OpenSans-SemiboldItalic-webfont.svg
│ ├── OpenSans-SemiboldItalic-webfont.ttf
│ └── OpenSans-SemiboldItalic-webfont.woff
├── icons
│ ├── home.svg
│ └── search.svg
├── scripts
│ ├── linenumber.js
│ └── pagelocation.js
└── styles
│ ├── collapse.css
│ ├── jsdoc-default.css
│ ├── prettify-jsdoc.css
│ └── prettify-tomorrow.css
└── tmpl
├── augments-spread.tmpl
├── augments.tmpl
├── container.tmpl
├── details.tmpl
├── example.tmpl
├── examples.tmpl
├── exceptions.tmpl
├── layout.tmpl
├── mainpage.tmpl
├── members.tmpl
├── method.tmpl
├── params.tmpl
├── properties.tmpl
├── returns.tmpl
├── source.tmpl
├── tutorial.tmpl
├── type-spread.tmpl
└── type.tmpl
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "comments": false,
3 | "presets": ["@babel/preset-env", "@babel/preset-react",
4 | [
5 | 'minify',
6 | {
7 | "builtIns": false,
8 | "deadcode": true,
9 | "mangle": {
10 | "exclude": ["r", "o", "n"]
11 | }
12 | }
13 | ]],
14 | "plugins": [
15 | "@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime"]
16 | }
17 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Either detailed steps to reproduce the behavior or an example project.
15 |
16 | **Expected behavior**
17 | A clear and concise description of what you expected to happen.
18 |
19 | **Screenshots**
20 | If applicable, add screenshots to help explain your problem.
21 |
22 | **Desktop (please complete the following information):**
23 | - OS: [e.g. iOS]
24 | - Browser [e.g. chrome, safari]
25 | - Version [e.g. 22]
26 |
27 | **Smartphone (please complete the following information):**
28 | - Device: [e.g. iPhone6]
29 | - OS: [e.g. iOS8.1]
30 | - Browser [e.g. stock browser, safari]
31 | - Version [e.g. 22]
32 |
33 | **Additional context**
34 | Add any other context about the problem here.
35 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/js-coroutines.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": false,
3 | "printWidth": 120,
4 | "tabWidth": 4,
5 | "singleQuote": true,
6 | "trailingComma": "es5",
7 | "jsxBracketSameLine": false,
8 | "arrowParens": "always",
9 | "semi": false,
10 | "bracketSpacing": true
11 | }
12 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.
4 |
5 | Please note we have a code of conduct, please follow it in all your interactions with the project.
6 |
7 | ## Pull Request Process
8 |
9 | Update the CHANGELOG.md with details of changes to the interface, this includes new functions and updates to existing functions.
10 | Increase the version numbers. The versioning scheme we use is SemVer.
11 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Pull Request Template
2 |
3 | ## Description
4 |
5 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
6 |
7 | Fixes # (issue)
8 |
9 | ## Type of change
10 |
11 | Please delete options that are not relevant.
12 |
13 | - [ ] Bug fix (non-breaking change which fixes an issue)
14 | - [ ] New feature (non-breaking change which adds functionality)
15 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
16 | - [ ] This change requires a documentation update
17 |
18 | ## How Has This Been Tested?
19 |
20 | Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
21 |
22 | **Test Configuration**:
23 |
24 | * Hardware:
25 | * Toolchain:
26 |
27 | ## Checklist:
28 |
29 | - [ ] I have performed a self-review of my own code
30 | - [ ] I have commented my code, particularly in hard-to-understand areas
31 | - [ ] I have made corresponding changes to the documentation
32 | - [ ] My changes generate no new warnings
33 | - [ ] I have added tests that prove my fix is effective or that my feature works
34 | - [ ] I have checked my code and corrected any misspellings
35 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/dist/append-async.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.appendAsync=void 0;var _wrappers=require("./wrappers"),_append=require("./append"),appendAsync=(0,_wrappers.wrapAsPromise)(_append.append);exports.appendAsync=appendAsync;
--------------------------------------------------------------------------------
/dist/append.js:
--------------------------------------------------------------------------------
1 | "use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.append=append;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_forEach=require("./for-each"),_wrappers=require("./wrappers"),_marked=_regenerator.default.mark(append);function append(b,c){var d;return _regenerator.default.wrap(function(a){for(;;)switch(a.prev=a.next){case 0:return d=b.length,a.next=3,!0;case 3:return b.length+=c.length,void(a.next=6);case 6:return a.delegateYield((0,_forEach.forEach)(c,(0,_wrappers.yielding)(function(c,a){return b[a+d]=c})),"t0",7);case 7:return a.abrupt("return",b);case 8:case"end":return a.stop();}},_marked)}
--------------------------------------------------------------------------------
/dist/array-utilities.js:
--------------------------------------------------------------------------------
1 | "use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.exitWith=exitWith,exports.doReturn=void 0;var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty")),doReturn=Symbol("return");exports.doReturn=doReturn;function exitWith(a){var b;return b={},(0,_defineProperty2.default)(b,doReturn,!0),(0,_defineProperty2.default)(b,"value",a),b}
--------------------------------------------------------------------------------
/dist/async-array-wrappers.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.everyAsync=void 0;var _asyncWrapperUtils=require("./async-wrapper-utils"),_every=require("./every"),everyAsync=(0,_asyncWrapperUtils.wrapAsPromiseAndYieldFn)(_every.every);exports.everyAsync=everyAsync;
--------------------------------------------------------------------------------
/dist/async-compression-wrappers.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.base64Decompress=exports.base64decompressFromUTF16Async=exports.decompressAsync=exports.decompressFromEncodedURIComponentAsync=exports.decompressFromUint8ArrayAsync=exports.decompressFromUTF16Async=exports.decompressFromBase64Async=exports.base64Compress=exports.base64CompressToUTF16Async=exports.compressAsync=exports.compressToEncodedURIComponentAsync=exports.compressToUint8ArrayAsync=exports.compressToUTF16Async=exports.compressToBase64Async=void 0;var _wrappers=require("./wrappers"),_base64String=require("./lz-string/base64-string"),_lzString=require("./lz-string/lz-string"),compressToBase64Async=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.compressToBase64);exports.compressToBase64Async=compressToBase64Async;var compressToUTF16Async=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.compressToUTF16);exports.compressToUTF16Async=compressToUTF16Async;var compressToUint8ArrayAsync=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.compressToUint8Array);exports.compressToUint8ArrayAsync=compressToUint8ArrayAsync;var compressToEncodedURIComponentAsync=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.compressToEncodedURIComponent);exports.compressToEncodedURIComponentAsync=compressToEncodedURIComponentAsync;var compressAsync=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.compress);exports.compressAsync=compressAsync;var base64CompressToUTF16Async=(0,_wrappers.wrapAsPromise)(_base64String.Base64StringGenerator.compressToUTF16);exports.base64CompressToUTF16Async=base64CompressToUTF16Async;var base64Compress=(0,_wrappers.wrapAsPromise)(_base64String.Base64StringGenerator.compress);exports.base64Compress=base64Compress;var decompressFromBase64Async=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.decompressFromBase64);exports.decompressFromBase64Async=decompressFromBase64Async;var decompressFromUTF16Async=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.decompressFromUTF16);exports.decompressFromUTF16Async=decompressFromUTF16Async;var decompressFromUint8ArrayAsync=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.decompressFromUint8Array);exports.decompressFromUint8ArrayAsync=decompressFromUint8ArrayAsync;var decompressFromEncodedURIComponentAsync=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.decompressFromURIComponent);exports.decompressFromEncodedURIComponentAsync=decompressFromEncodedURIComponentAsync;var decompressAsync=(0,_wrappers.wrapAsPromise)(_lzString.LZStringGenerator.decompress);exports.decompressAsync=decompressAsync;var base64decompressFromUTF16Async=(0,_wrappers.wrapAsPromise)(_base64String.Base64StringGenerator.decompressFromUTF16);exports.base64decompressFromUTF16Async=base64decompressFromUTF16Async;var base64Decompress=(0,_wrappers.wrapAsPromise)(_base64String.Base64StringGenerator.decompress);exports.base64Decompress=base64Decompress;
--------------------------------------------------------------------------------
/dist/async-json-wrappers.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseAsync=exports.stringifyAsync=void 0;var _wrappers=require("./wrappers"),_parse=require("./yastjson/lib/parse"),_json=require("./json"),stringifyAsync=(0,_wrappers.wrapAsPromise)(_json.stringify);exports.stringifyAsync=stringifyAsync;var parseAsync=(0,_wrappers.wrapAsPromise)(_parse.parse);exports.parseAsync=parseAsync;
--------------------------------------------------------------------------------
/dist/async-wrapper-utils.js:
--------------------------------------------------------------------------------
1 | "use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.wrapAsPromiseAndYieldFn=wrapAsPromiseAndYieldFn;var _wrappers=require("./wrappers"),_run=_interopRequireDefault(require("./run")),_call=require("./call");function wrapAsPromiseAndYieldFn(a){var b=function(b,c){for(var d=arguments.length,e=Array(2} a promise for destination after appending
10 | */
11 | export const appendAsync = wrapAsPromise(append)
12 |
--------------------------------------------------------------------------------
/dist/es6/append.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {yielding} from './wrappers'
3 |
4 | /**
5 | * Appends one array to another
6 | * @generator
7 | * @param {Array} array1 - the destination
8 | * @param {Array} array2 - the source
9 | * @returns {Generator<*, Array, *>} returns array1
10 | * @example
11 | *
12 | * // Updates array1
13 | * yield * append(array1, array2)
14 | */
15 | export function* append(array1, array2) {
16 | const l = array1.length
17 | yield true
18 | array1.length += array2.length
19 | yield
20 | yield* forEach(
21 | array2,
22 | yielding((a, i) => (array1[i + l] = a))
23 | )
24 |
25 | return array1
26 | }
27 |
--------------------------------------------------------------------------------
/dist/es6/array-utilities.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @callback Filter
3 | * @param {any} element
4 | * @param {number} index
5 | * @param {Array} collection
6 | * @returns {Generator} a generator for a value of true if included in the filter
7 | */
8 |
9 | /**
10 | * @callback Map
11 | * @param {any} element
12 | * @param {number} index
13 | * @param {Array} collection
14 | * @returns {any} updated item
15 | */
16 |
17 | /**
18 | * @callback Reduce
19 | * @param {any} accumulator
20 | * @param {any} element
21 | * @param {number} index
22 | * @param {Array} collection
23 | * @returns {any} updated value
24 | */
25 |
26 | /**
27 | * @callback Process
28 | * @param {any} value - the value being processed
29 | * @param {number|string} key - the key or index of the value
30 | * @param {Array} collection - the collection being iterated
31 | */
32 |
33 | export const doReturn = Symbol('return')
34 |
35 | export function exitWith(value) {
36 | return {[doReturn]: true, value}
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/dist/es6/async-array-wrappers.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {every} from './every'
3 |
4 | /**
5 | * Asynchronously check if every element in an array matches
6 | * a predicate
7 | * @function everyAsync
8 | * @param {Array} array
9 | * @param {Filter} fn
10 | * @returns {Promise.} promise for true if all items matched the filter
11 | */
12 | export const everyAsync = wrapAsPromiseAndYieldFn(every)
13 |
14 | /**
15 | * @callback SortFunction
16 | * @param {any} item1
17 | * @param {any} item2
18 | * @returns < 0 if item 2 is bigger than item 1, === 0 if they are the same else > 0
19 | */
20 |
21 | /**
22 | * @callback ExtractFunction
23 | * @param {any} item1
24 | * @returns {any} the value to sort item 1 by
25 | */
26 |
27 |
28 |
--------------------------------------------------------------------------------
/dist/es6/async-json-wrappers.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromise} from './wrappers'
2 | import {parse} from './yastjson/lib/parse'
3 | import {stringify} from './json'
4 |
5 | /**
6 | * Asynchronously stringify data into JSON
7 | * @function
8 | * @name stringifyAsync
9 | * @param {any} data - Object to store
10 | * @returns {Promise.} a Promise for the JSON representation of data
11 | */
12 | export const stringifyAsync = wrapAsPromise(stringify)
13 | /**
14 | * Asynchronously parse JSON into an object
15 | * @function parseAsync
16 | * @param {String} json - the JSON to be parsed
17 | * @returns {Promise.} a Promise for the parsed JSON
18 | */
19 | export const parseAsync = wrapAsPromise(parse)
20 |
--------------------------------------------------------------------------------
/dist/es6/async-wrapper-utils.js:
--------------------------------------------------------------------------------
1 | import {yielding} from './wrappers'
2 | import run from './run'
3 | import {call} from './call'
4 |
5 | /**
6 | * Create a promised function
7 | * @param {Function} fn
8 | * @returns {Function}
9 | */
10 | export function wrapAsPromiseAndYieldFn(fn) {
11 | const result = function (array, processor, ...params) {
12 | return run(fn(array, yielding(processor), ...params))
13 | }
14 | result.with = function (...params) {
15 | return call(result, ...params)
16 | }
17 | return result
18 | }
19 |
--------------------------------------------------------------------------------
/dist/es6/async-wrappers.js:
--------------------------------------------------------------------------------
1 | export * from './async-array-wrappers'
2 | export * from './async-compression-wrappers'
3 | export * from './async-json-wrappers'
4 | export {sortAsync} from './sort-async'
5 | export {findAsync} from './find-async'
6 | export {findIndexAsync} from './find-index-async'
7 | export {mapAsync} from './map-async'
8 | export {filterAsync} from './filter-async'
9 | export {reduceAsync} from './reduce-async'
10 | export {appendAsync} from './append-async'
11 | export {concatAsync} from './concat-async'
12 | export {forEachAsync} from './for-each-async'
13 | export {someAsync} from './some-async'
14 | export {includesAsync} from './includes-async'
15 | export {indexOfAsync} from './index-of-async'
16 | export {lastIndexOfAsync} from './last-index-of-async'
17 | export {keyByAsync} from './key-by-async'
18 | export {groupByAsync} from './group-by-async'
19 | export {uniqueByAsync} from './unique-by-async'
20 |
--------------------------------------------------------------------------------
/dist/es6/branch.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Branches a pipeline by starting another "continuation" with
5 | * the current parameters. Starts a function but the pipeline
6 | * continues immediately creating two execution contexts
7 | * @param {Function} fn - the function to start - can be async or generator
8 | */
9 | export function branch(fn) {
10 | return function (params) {
11 | let result = fn.call(this, params)
12 | if (result) {
13 | if (result.next) {
14 | run(result).catch(console.error)
15 | } else if (result.then) {
16 | result.catch(console.error)
17 | }
18 | }
19 | return params
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/dist/es6/call.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Create a version of a function with its end
3 | * parameters supplied
4 | * @param {Function|GeneratorFunction|AsyncFunction} fn - the function to configure
5 | * @param {...any[]} config - the additional parameters to pass
6 | * @returns {Function}
7 | */
8 | export function call(fn, ...config) {
9 | return function (...params) {
10 | return fn.apply(this, [...params, ...config])
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/dist/es6/compose.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Create a function that executes a pipeline of
5 | * functions asynchronously, the function executes the list in
6 | * REVERSE order, allowing you to "compose on" a new function
7 | * at the head of the chain
8 | * @param {...(Function|Promise|Array<(Promise|Function|GeneratorFunction|AsyncFunction)>|GeneratorFunction|AsyncFunction)} fns - the pipeline to execute
9 | * @returns {AsyncFunction} an async function to execute the pipeline
10 | */
11 | export function compose(...fns) {
12 | return async function (params) {
13 | let result = params
14 |
15 | let list = fns.flat(Infinity)
16 | for (let i = list.length - 1; i >= 0; i--) {
17 | let fn = list[i]
18 | if (!fn) continue
19 | let nextResult = fn.call(this, result)
20 | if (nextResult) {
21 | if (nextResult.next) {
22 | result = await run(nextResult)
23 | } else if (nextResult.then) {
24 | result = await nextResult
25 | } else {
26 | result = nextResult
27 | }
28 | }
29 | }
30 | return result
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/dist/es6/concat-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromise} from './wrappers'
2 | import {concat} from './concat'
3 |
4 | /**
5 | * Concatenates 2 arrays into a new array
6 | * @function concatAsync
7 | * @param {Array} array1
8 | * @param {Array} array2
9 | * @returns {Promise.} a promise for combined array
10 | */
11 | export const concatAsync = wrapAsPromise(concat)
12 |
--------------------------------------------------------------------------------
/dist/es6/concat.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {yielding} from './wrappers'
3 |
4 | /**
5 | * Concatenate two arrays into a new array
6 | * @generator
7 | * @param {Array} array1
8 | * @param {Array} array2
9 | * @returns {Generator<*, Array, *>} the concatenated arrays
10 | * @example
11 | *
12 | * const concatenated = yield * concat(array1, array2)
13 | */
14 | export function* concat(array1, array2) {
15 | yield true
16 | const result = new Array(array1.length + array2.length)
17 | yield
18 | const l = array1.length
19 | yield* forEach(
20 | array1,
21 | yielding((a, i) => (result[i] = a))
22 | )
23 | yield* forEach(
24 | array2,
25 | yielding((a, i) => (result[i + l] = a))
26 | )
27 | return result
28 | }
29 |
--------------------------------------------------------------------------------
/dist/es6/coroutines.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * A coroutine to be run during the gaps in other processing and animation.
4 | *
5 | *
6 | * The coroutine should yield regularly to do a time check. A plain yield will cause
7 | * a check against the standard time remaining specified when running. yield {number} will
8 | * check that number milliseconds are available and yield true will abandon any more
9 | * processing on the current frame.
10 | *
11 | * @callback Coroutine
12 | * @generator
13 | * @yields {number} either undefined to perform a standard time remaining check, a number of milliseconds required for the next step or true if we should abandon the current frame
14 | * @returns the result of the function if any to be returned to the caller
15 | */
16 |
17 | /**
18 | * @typedef IteratorResult
19 | * @object
20 | * @property {any} [value] - the returned value
21 | * @property {boolean} done - whether the iterator is complete
22 | */
23 |
24 | /**
25 | * @interface Iterator
26 | */
27 |
28 | /**
29 | * Get the next value
30 | * @function
31 | * @name Iterator#next
32 | * @param {any} value - value to send to the coroutine
33 | * @returns {IteratorResult}
34 | */
35 |
36 | /**
37 | * A coroutine to be used in high priority to animate.
38 | *
39 | * Executing a yield will cause the routine to resume at the start
40 | * of the next frame.
41 | * @callback AnimationCoroutine
42 | * @generator
43 | * @returns the result of the function if any to be returned to the caller
44 | */
45 |
46 |
47 | /**
48 | * @callback GeneratorFunction
49 | * @generator
50 | * @param {...*} params - the parameters to pass
51 | * @returns {*} the result of the coroutine
52 | */
53 |
54 | /**
55 | * @callback AsyncFunction
56 | * @param {*} params - the parameters to pass
57 | * @async
58 | * @returns {*} result of calling the function
59 | */
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/dist/es6/every.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {exitWith} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @returns {Generator<*, boolean, *>} true if all of the collection items matched the filter
9 | * @example
10 | *
11 | * if(! yield * every(records, yielding(r=>r.valid))) return
12 | */
13 | export function* every(collection, fn) {
14 | let result = true
15 | yield* forEach(collection, function* (value, key) {
16 | if (!(yield* fn(value, key, collection))) {
17 | result = false
18 | return exitWith(false)
19 | }
20 | })
21 | return result
22 | }
23 |
--------------------------------------------------------------------------------
/dist/es6/filter-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {filter} from './filter'
3 |
4 | /**
5 | * Filters an array asynchronously
6 | * @function filterAsync
7 | * @param {Array} array
8 | * @param {Filter} filter
9 | * @returns {Promise.} promise for the filtered array
10 | */
11 | export const filterAsync = wrapAsPromiseAndYieldFn(filter)
12 |
--------------------------------------------------------------------------------
/dist/es6/filter.js:
--------------------------------------------------------------------------------
1 | import {isObject} from './is-object'
2 | import {forEach} from './for-each'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @returns {Generator<*, Object|Array, *>} collection of elements matching the filter
9 | * @example
10 | *
11 | * const filtered = yield * filter(array, yielding(v=>v.value > 1000, 100))
12 | */
13 | export function* filter(collection, fn) {
14 | if (isObject(collection)) {
15 | let result = {}
16 | yield* forEach(collection, function* (value, key, array) {
17 | if (yield* fn(value, key, array)) {
18 | result[key] = value
19 | }
20 | })
21 | return result
22 | } else {
23 | let result = []
24 | yield* forEach(collection, function* (value, key, array) {
25 | if (yield* fn(value, key, array)) {
26 | result.push(value)
27 | }
28 | })
29 | return result
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/dist/es6/find-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {find} from './find'
3 |
4 | /**
5 | * Finds an item in an array asynchronously
6 | * @function findAsync
7 | * @param {Array} array
8 | * @param {Filter} filter
9 | * @returns {Promise.} promise for the item found or null if no match
10 | */
11 | export const findAsync = wrapAsPromiseAndYieldFn(find)
12 |
--------------------------------------------------------------------------------
/dist/es6/find-index-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {findIndex} from './find-index'
3 |
4 | /**
5 | * Finds an item index in an array asynchronously
6 | * @function findIndexAsync
7 | * @param {Array} array
8 | * @param {Filter} filter
9 | * @returns {Promise.} promise for the index of the first item to pass the filter or -1
10 | */
11 | export const findIndexAsync = wrapAsPromiseAndYieldFn(findIndex)
12 |
--------------------------------------------------------------------------------
/dist/es6/find-index.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {exitWith} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @returns {Generator<*, number, *>} Index of matching element or -1
9 | * @example
10 | *
11 | * if(-1 === yield * findIndex(records, yielding(v=>v.id === '123')))
12 | * return
13 | */
14 | export function* findIndex(collection, fn, start) {
15 | let output = -1
16 | yield* forEach(
17 | collection,
18 | function* (value, key) {
19 | let result = yield* fn(value, key, collection)
20 | if (result) {
21 | output = key
22 | return exitWith(key)
23 | }
24 | },
25 | start
26 | )
27 | return output
28 | }
29 |
--------------------------------------------------------------------------------
/dist/es6/find.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {exitWith} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @param {any} [start] - the key to start at
9 | * @returns {Generator<*, *, *>} the first matching value in the collection or null
10 | * @example
11 | *
12 | * const record = yield * find(arrayOfRecords, yielding(v=>v.id === '1234'))
13 | */
14 | export function* find(collection, fn, start) {
15 | let output = undefined
16 | yield* forEach(
17 | collection,
18 | function* (value, key) {
19 | let result = yield* fn(value, key, collection)
20 | if (result) {
21 | output = value
22 | return exitWith(value)
23 | }
24 | },
25 | start
26 | )
27 | return output
28 | }
29 |
--------------------------------------------------------------------------------
/dist/es6/for-each-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {forEach} from './for-each'
3 |
4 | /**
5 | * Asynchronously loop over the elements of an array
6 | * @function forEachAsync
7 | * @param {Array} array
8 | * @param {Process} fn
9 | * @returns {Promise} promise for the end of the operation
10 | */
11 | export const forEachAsync = wrapAsPromiseAndYieldFn(forEach)
12 |
--------------------------------------------------------------------------------
/dist/es6/for-each.js:
--------------------------------------------------------------------------------
1 | import {isObject} from './is-object'
2 | import {doReturn} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Process} fn
8 | * @param {number|string} [start]
9 | * @returns {Generator<*, *, *>}
10 | * @example
11 | * // Loop over all keys/value pairs in an object
12 | * yield * forEach(object, yielding((value, key)=> { ... }))
13 | *
14 | * // Loop over all the values in an array
15 | * yield * forEach(array, generatorFunction)
16 | *
17 | * function * generatorFunction(value, index) {
18 | * let i = 0
19 | * while(i < 10000) {
20 | * doSomething(value)
21 | * if(i % 100 === 0) yield
22 | * }
23 | * }
24 | */
25 | export function* forEach(collection, fn, start) {
26 | if (isObject(collection)) {
27 | let started = !start
28 | for (let key in collection) {
29 | if (!started) {
30 | started = key === start
31 | }
32 | if (started) {
33 | if (Object.prototype.hasOwnProperty.call(collection, key)) {
34 | let result = yield* fn(collection[key], key, collection)
35 | if (result && result[doReturn]) return result.value
36 | }
37 | }
38 | }
39 | } else {
40 | for (let index = start || 0, length = collection.length; index < length; index++) {
41 | let result = yield* fn(collection[index], index, collection)
42 | if (result && result[doReturn]) return result.value
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/dist/es6/group-by-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {groupBy} from './group-by'
3 |
4 | /**
5 | * Promises the creation of an object composed of keys generated from the results
6 | * of running each element of collection thru then supplied function.
7 | * The corresponding value of each key is an collection of the elements responsible
8 | * for generating the key.
9 | *
10 | * @param {Array|Object} collection
11 | * @param {Map} fn
12 | * @returns {Promise<{}>}
13 | */
14 | export const groupByAsync = wrapAsPromiseAndYieldFn(groupBy)
15 |
--------------------------------------------------------------------------------
/dist/es6/group-by.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates an object composed of keys generated from the results
3 | * of running each element of collection thru then supplied function.
4 | * The corresponding value of each key is an collection of the elements responsible
5 | * for generating the key.
6 | *
7 | * @param {Array|Object} collection
8 | * @param {Map} fn
9 | * @returns {Generator<*, {}, *>} a generator for the new object
10 | * @example
11 | *
12 | * let groups = yield * groupBy(records, yielding(v=>v.category))
13 | *
14 | * ...
15 | *
16 | * console.log(groups['category1']) // -> [{id: 1, ...}, {id: 2, ...}]
17 | *
18 | */
19 | export function* groupBy(collection, fn) {
20 | let result = {}
21 | let index = 0
22 | for (let item of collection) {
23 | let key = yield* fn(item, index++, collection)
24 | const array = (result[key] = result[key] || [])
25 | array.push(item)
26 | }
27 | return result
28 | }
29 |
--------------------------------------------------------------------------------
/dist/es6/includes-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {includes} from './includes'
3 |
4 | /**
5 | * Returns a promise returning true if an array includes a value
6 | * @param array
7 | * @param value
8 | * @returns Promise
9 | * @example
10 | * if(await includesAsync(someArray, 'error')) {
11 | * ...
12 | * }
13 | */
14 | export const includesAsync = wrapAsPromiseAndYieldFn(includes)
15 |
--------------------------------------------------------------------------------
/dist/es6/includes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns true if an array includes a value
3 | * @param {Array} array
4 | * @param {any} value
5 | * @returns {Generator<*, boolean, *>}
6 | * @example
7 | *
8 | * prices = price * (yield * includes(items, yielding(v=>v.discount))) ? .4 : 1
9 | */
10 | export function* includes(array, value) {
11 | for (let i = 0, l = array.length; i < l; i++) {
12 | if (array[i] === value) return true
13 | if ((i & 63) === 0) yield
14 | }
15 | return false
16 | }
17 |
--------------------------------------------------------------------------------
/dist/es6/index-of-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {indexOf} from './index-of'
3 |
4 | /**
5 | * Returns a promise for the first index of an item in an array
6 | * @param array - the array to scan
7 | * @param value - the value to search for
8 | * @returns {Promise}
9 | */
10 | export const indexOfAsync = wrapAsPromiseAndYieldFn(indexOf)
11 |
--------------------------------------------------------------------------------
/dist/es6/index-of.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns a generator for an index of an item in an array
3 | * @param {Array} array - the array to scan
4 | * @param {*} value - the value to search for
5 | * @returns {Generator<*, number, *>}
6 | */
7 | export function* indexOf(array, value) {
8 | for (let i = 0, l = array.length; i < l; i++) {
9 | if (array[i] === value) return i
10 | if ((i & 63) === 0) yield
11 | }
12 | return -1
13 | }
14 |
--------------------------------------------------------------------------------
/dist/es6/is-object.js:
--------------------------------------------------------------------------------
1 | export function isObject(v) {
2 | return typeof v === 'object' && !Array.isArray(v)
3 | }
4 |
--------------------------------------------------------------------------------
/dist/es6/key-by-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {keyBy} from './key-by'
3 |
4 | /**
5 | * Promises the creation an object composed of keys generated from the results
6 | * of running each element of collection thru then supplied function.
7 | * The corresponding value of each key is the last element responsible
8 | * for generating the key.
9 | *
10 | * @param {Array|Object} collection
11 | * @param {Map} fn
12 | * @returns {Promise<{}>}
13 | */
14 | export const keyByAsync = wrapAsPromiseAndYieldFn(keyBy)
15 |
--------------------------------------------------------------------------------
/dist/es6/key-by.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 |
3 | /**
4 | * Creates an object composed of keys generated from the results
5 | * of running each element of collection thru then supplied function.
6 | * The corresponding value of each key is the last element responsible
7 | * for generating the key.
8 | *
9 | * @param {Array|Object} collection
10 | * @param {Map} fn
11 | * @returns {Generator<*, {}, *>} a generator for the new object
12 | * @example
13 | *
14 | * let lookup = yield * keyBy(records, yielding(r=>r.id))
15 | *
16 | * ...
17 | *
18 | * let row = lookup[id]
19 | *
20 | */
21 | export function* keyBy(collection, fn) {
22 | let result = {}
23 | yield* forEach(collection, function* (value, key) {
24 | let newKey = yield* fn(value, key, collection)
25 | result[newKey] = value
26 | })
27 | return result
28 | }
29 |
--------------------------------------------------------------------------------
/dist/es6/last-index-of-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {lastIndexOf} from './last-index-of'
3 |
4 | /**
5 | * Returns a promise for the last index of an item in an array
6 | * @param array - the array to scan
7 | * @param value - the value to search for
8 | * @returns {Promise}
9 | */
10 | export const lastIndexOfAsync = wrapAsPromiseAndYieldFn(lastIndexOf)
11 |
--------------------------------------------------------------------------------
/dist/es6/last-index-of.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns a generator for an index of an item in an array
3 | * @param {Array} array - the array to scan
4 | * @param {*} value - the value to search for
5 | * @returns {Generator<*, number, *>}
6 | * @example
7 | *
8 | * let last = yield * lastIndexOf(collection, record)
9 | *
10 | */
11 | export function* lastIndexOf(array, value) {
12 | for (let i = array.length - 1; i >= 0; i--) {
13 | if (array[i] === value) return i
14 | if ((i & 63) === 0) yield
15 | }
16 | return -1
17 | }
18 |
--------------------------------------------------------------------------------
/dist/es6/map-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {map} from './map'
3 |
4 | /**
5 | * Maps the contents of an array asynchronously
6 | * @function mapAsync
7 | * @param {Array} array
8 | * @param {Map} mapFn
9 | * @returns {Promise.} promise for the mapped array
10 | */
11 | export const mapAsync = wrapAsPromiseAndYieldFn(map)
12 |
--------------------------------------------------------------------------------
/dist/es6/map.js:
--------------------------------------------------------------------------------
1 | import {isObject} from './is-object'
2 | import {forEach} from './for-each'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Map} fn
8 | * @returns {Generator<*, Array|Object, *>} new collection of mapped values
9 | * @example
10 | *
11 | * const values = yield * map(array, yielding(v=>v ** 2))
12 | *
13 | */
14 | export function* map(collection, fn) {
15 | let result = isObject(collection) ? {} : []
16 | yield* forEach(collection, function* (value, key) {
17 | result[key] = yield* fn(value, key, collection)
18 | })
19 | return result
20 | }
21 |
--------------------------------------------------------------------------------
/dist/es6/pipe.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Create a function that executes a pipeline of
5 | * functions asynchronously
6 | * @param {...(Function|Promise|Array<(Promise|Function|GeneratorFunction|AsyncFunction)>|GeneratorFunction|AsyncFunction)} fns - the pipeline to execute
7 | * @returns {AsyncFunction} an async function to execute the pipeline
8 | */
9 | export function pipe(...fns) {
10 | return async function (params) {
11 | let result = params
12 | for (let fn of fns.flat(Infinity)) {
13 | if (!fn) continue
14 | let nextResult = fn.call(this, result)
15 | if (nextResult) {
16 | if (nextResult.next) {
17 | result = await run(nextResult)
18 | } else if (nextResult.then) {
19 | result = await nextResult
20 | } else {
21 | result = nextResult
22 | }
23 | }
24 | }
25 | return result
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/dist/es6/reduce-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {reduce} from './reduce'
3 |
4 | /**
5 | * Performs a reduce on an array asynchronously
6 | * @function reduceAsync
7 | * @param {Array} array
8 | * @param {Reduce} reduceFn
9 | * @param {any} initialValue
10 | * @returns {Promise.} a promise for the reduced value
11 | */
12 | export const reduceAsync = wrapAsPromiseAndYieldFn(reduce)
13 |
--------------------------------------------------------------------------------
/dist/es6/reduce.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 |
3 | /**
4 | * @param {Array|Object} target
5 | * @param {Reduce} fn
6 | * @param {any} [initial]
7 | * @returns {Generator<*, *, *>} The result of processing the reduction function on all
8 | * of the items in the target
9 | * @example
10 | *
11 | * async function sumAge(items) {
12 | * const output = await reduceAsync(items, (acc,cur)=>acc += cur.age, 0)
13 | * }
14 | */
15 | export function* reduce(target, fn, initial) {
16 | let result = initial !== undefined ? initial : target[0]
17 | let first = true
18 | yield* forEach(target, function* (item, key) {
19 | if (first && !initial) {
20 | result = item
21 | first = false
22 | } else {
23 | result = yield* fn(result, item, key, target)
24 | }
25 | })
26 | return result
27 | }
28 |
--------------------------------------------------------------------------------
/dist/es6/repeat.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Create a function that repeats a function multiple times
5 | * passing the output of each iteration as the input to the next
6 | * @param {Function} fn - the function to repeat
7 | * @param {Number} times - the number of times to repeat
8 | * @returns {AsyncFunction} - a async function that repeats the operation
9 | */
10 | export function repeat(fn, times) {
11 | return async function (params) {
12 | let result = params
13 | for (let i = 0; i < times; i++) {
14 | result = fn.call(this, result)
15 | if (result.next) {
16 | result = await run(result)
17 | } else if (result.then) {
18 | result = await result
19 | }
20 | }
21 | return result
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/dist/es6/singleton.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Creates a singleton executor of a generator function.
5 | * If the function is currently running it will be
6 | * terminated with the defaultValue and a new one started.
7 | *
8 | * This would often be used with a UI to cancel a previous calculation
9 | * and begin updates on a new one.
10 | *
11 | * @param {Function} fn - the generator function to wrap
12 | * @param {any} [defaultValue] - a value to be returned if the current execution is
13 | * terminated by a new one starting
14 | * @returns {function(...[*]): Promise} a function to execute the
15 | * generator and return the value
16 | * @example
17 | *
18 | * const job = singleton(function * (array, value) {
19 | * let output = []
20 | * for(let item of array) {
21 | * if(output.length % 100 === 0) yield
22 | * output.push(complexCalculation(array, value))
23 | * }
24 | * return output
25 | * }, [])
26 | *
27 | * function doSomething(array) {
28 | * job(array, 2002).then(console.log)
29 | * }
30 | *
31 | * doSomething(bigArray)
32 | * doSomething(otherArray) // -> console.log([]) from first one
33 | *
34 | */
35 | export function singleton(fn, defaultValue) {
36 | let promise = null
37 | let extraPromises = []
38 | let result = (...params) => {
39 | if (promise) {
40 | extraPromises.forEach(p => p.terminate())
41 | extraPromises = []
42 | promise.terminate(defaultValue)
43 | }
44 | return promise = result._promise = run(fn(...params))
45 | }
46 | result.join = function (promise) {
47 | extraPromises.push(promise)
48 | return promise
49 | }
50 | return result
51 | }
52 |
--------------------------------------------------------------------------------
/dist/es6/some-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {some} from './some'
3 |
4 | /**
5 | * Asynchronously apply an array some operation
6 | * returning a promise for true if at least
7 | * one item matches
8 | * @function someAsync
9 | * @param {Array} array
10 | * @param {Filter} fn
11 | * @returns {Promise.} promise for true if at least one item matched the filter
12 | */
13 | export const someAsync = wrapAsPromiseAndYieldFn(some)
14 |
--------------------------------------------------------------------------------
/dist/es6/some.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {exitWith} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @returns {Generator<*, boolean, *>} true if at least one item matched the filter
9 | * @example
10 | *
11 | *
12 | * if(yield * some(collection, yielding(v=>v > 2000)) {
13 | * ...
14 | * }
15 | */
16 | export function* some(collection, fn) {
17 | let result = false
18 | yield* forEach(collection, function* (value, key) {
19 | if (yield* fn(value, key, collection)) {
20 | result = true
21 | return exitWith(true)
22 | }
23 | })
24 | return result
25 | }
26 |
--------------------------------------------------------------------------------
/dist/es6/sort-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromise} from './wrappers'
2 | import {sort} from './timsort'
3 |
4 | /**
5 | *
Sort an array (in place) by a sorting function
6 | *
Sorts an array in place asynchronously. This function is a yielding
7 | * implementation of Timsort (standard sort used in modern browsers). Timsort
8 | * is fast and stable making it ideal for multi-key sorts. It it not as fast
9 | * as Quicksort.
10 | * @function sortAsync
11 | * @param {Array} array - The array to sort
12 | * @param {SortFunction|ExtractFunction} sort - The method to sort the array
13 | * @returns {Promise.} a promise for the sorted array
14 | * @example
15 | * async function process(data) {
16 | * return await sortAsync(data, v=>v.someProperty)
17 | * }
18 | */
19 | export const sortAsync = wrapAsPromise(sort)
20 |
--------------------------------------------------------------------------------
/dist/es6/tap.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Tap into a pipeline to call a function that will probably
5 | * perform side effects but should not modify the result, its
6 | * return value is ignored
7 | * @param {Function} fn - a function to be called at this point in
8 | * the pipeline
9 | * @returns {AsyncFunction} returning the passed in parameters
10 | */
11 | export function tap(fn) {
12 | return async function (params) {
13 | let result = fn.call(this, params)
14 | if (result) {
15 | if (result.next) {
16 | await run(result)
17 | } else if (result.then) {
18 | await result
19 | }
20 | }
21 | return params
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/dist/es6/unique-by-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {uniqueBy} from './unique-by'
3 |
4 | /**
5 | * Promises the creation of an array with the unique values from the
6 | * input array, the routine is supplied with a
7 | * function that determines on what the array should
8 | * be made unique.
9 | * @param {Array} array
10 | * @param {Map} [fn] - the function to determine uniqueness, if
11 | * omitted then the item itself is used
12 | * @returns {Promise} unique array
13 | */
14 | export const uniqueByAsync = wrapAsPromiseAndYieldFn(uniqueBy)
15 |
--------------------------------------------------------------------------------
/dist/es6/unique-by.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Create an array with the unique values from the
3 | * input array, the routine is supplied with a
4 | * function that determines on what the array should
5 | * be made unique.
6 | * @param {Array} array
7 | * @param {Map} [fn] - the function to determine uniqueness, if
8 | * omitted then the item itself is used
9 | * @returns {Generator<*, Array, *>}
10 | * @example
11 | *
12 | * const uniqueValues = yield * uniqueBy(records, yielding(r=>r.id))
13 | *
14 | */
15 | export function* uniqueBy(array, fn) {
16 | let set = new Set()
17 | let output = []
18 | let index = 0
19 | for (let item of array) {
20 | if (fn) {
21 | let key = yield* fn(item, index++, array)
22 | if (!set.has(key)) {
23 | output.push(item)
24 | set.add(key)
25 | }
26 | } else {
27 | if (!set.has(item)) {
28 | output.push(item)
29 | set.add(item)
30 | }
31 | }
32 | }
33 | return output
34 | }
35 |
--------------------------------------------------------------------------------
/dist/es6/update.js:
--------------------------------------------------------------------------------
1 | let requested = false
2 | let animationCallbacks = []
3 |
4 | function nextAnimationFrame(fn) {
5 | if (typeof window === 'undefined') throw new Error('Cannot run without a browser')
6 | if (animationCallbacks.length === 0 && !requested) {
7 | requested = true
8 | requestAnimationFrame(process)
9 | }
10 | animationCallbacks.push(fn)
11 | if (animationCallbacks.length > 10000) animationCallbacks = animationCallbacks.slice(-9000)
12 | }
13 |
14 | function process() {
15 | let callbacks = animationCallbacks
16 | if (callbacks.length) {
17 | requestAnimationFrame(process)
18 | } else {
19 | requested = false
20 | }
21 | animationCallbacks = []
22 | for (let callback of callbacks) {
23 | callback()
24 | }
25 | }
26 |
27 | /**
28 | * Start an animation coroutine, the animation will continue until
29 | * you return and will be broken up between frames by using a
30 | * yield.
31 | *
32 | * @param {AnimationCoroutine|Iterator} coroutine - The animation to run
33 | * @param {...*} [params] - Parameters to be passed to the animation function
34 | * @returns {Promise} a value that will be returned to the caller
35 | * when the animation is complete.
36 | * The promise returned by update has a terminate() method
37 | * that can be used to stop the routine.
38 | */
39 | export function update(coroutine, ...params) {
40 | if (typeof window === 'undefined') throw new Error('Requires a browser to run')
41 | let terminated = false
42 | let resolver = null
43 | const result = new Promise(function (resolve, reject) {
44 | resolver = resolve
45 | const iterator = coroutine.next ? coroutine : coroutine(...params)
46 | nextAnimationFrame(run)
47 |
48 | function run() {
49 | if (terminated) {
50 | iterator.return()
51 | return
52 | }
53 |
54 | try {
55 | const {value, done} = iterator.next()
56 | if (done) {
57 | resolve(value)
58 | return
59 | }
60 | } catch (e) {
61 | reject(e)
62 | return
63 | }
64 |
65 | nextAnimationFrame(run)
66 | }
67 | })
68 | result.terminate = function (result) {
69 | terminated = true
70 | if (resolver) {
71 | resolver(result)
72 | }
73 | }
74 | return result
75 | }
76 |
--------------------------------------------------------------------------------
/dist/es6/useInternalEngine.js:
--------------------------------------------------------------------------------
1 | import {getCallback, getNodeCallback} from './polyfill'
2 |
3 |
4 | export let request = typeof window === 'undefined' ? getNodeCallback() : window.requestIdleCallback
5 |
6 | /**
7 | * Call with true to use the polyfilled version of
8 | * the idle callback, can be more stable in certain
9 | * circumstances
10 | * @param {Boolean} internal
11 | */
12 | export function useInternalEngine(internal) {
13 | request = internal ? getCallback() : request
14 | }
15 |
--------------------------------------------------------------------------------
/dist/es6/wrappers.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | import run from './run'
4 | import {call} from './call'
5 |
6 | /**
7 | * Wraps a normal function into a generator function
8 | * that yields on a regular basis
9 | * @param {Function} fn - the function to be wrapped
10 | * @param {number} [frequency=8] -
11 | * the number of times the function should be called
12 | * before performing a yield
13 | * @returns {Coroutine} The wrapped yielding
14 | * version of the function passed
15 | */
16 | export function yielding(fn, frequency = 16) {
17 | let yieldCount = 0;
18 | if(fn._yielding) return fn;
19 | let result = function* (...params) {
20 | let result = fn(...params);
21 | if(result && result.then) {
22 | result = yield result
23 | }
24 | if (yieldCount++ % frequency === 0) {
25 | yield;
26 | }
27 | return result;
28 | };
29 | result._yielding = true
30 | return result
31 | }
32 |
33 | /**
34 | * @callback PromiseFn
35 | * @param {...*} [parameters] the parameters for the function
36 | * @return {Promise} a promise for the result of the function
37 | */
38 |
39 | /**
40 | * Returns a function that will execute the passed
41 | * Coroutine and return a Promise for its result. The
42 | * returned function will take any number of parameters
43 | * and pass them on to the coroutine.
44 | *
45 | * @param {Coroutine} coroutine - The coroutine to run
46 | * @returns {PromiseFn|Function} a function that can be called to execute the coroutine
47 | * and return its result on completion
48 | */
49 | export function wrapAsPromise(coroutine) {
50 | const result = function (...params) {
51 | return run(coroutine(...params))
52 | };
53 | result.with = function (...params) {
54 | return call(result, ...params)
55 | }
56 | return result
57 | }
58 |
59 | export function curryRight(fn, supplied, execute) {
60 | if(fn.length > supplied.length) {
61 | return function(...params) {
62 | return curryRight.call(this, fn, [...params, ...supplied], execute)
63 | }
64 | }
65 | return execute.apply(this, supplied)
66 | }
67 |
--------------------------------------------------------------------------------
/dist/es6/yastjson/lib/expression.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2020 5u9ar (zhuyingda)
3 | *
4 | * The above copyright notice and this permission notice shall be included in all
5 | * copies or substantial portions of the Software.
6 | *
7 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
13 | * SOFTWARE.
14 | */
15 | export const ExprType = {
16 | Json: "j",
17 | Array: "a",
18 | Object: "o",
19 | Prop: "p",
20 | Value: "v",
21 | };
22 |
--------------------------------------------------------------------------------
/dist/es6/yastjson/lib/parse.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2020 5u9ar (zhuyingda) (c) 2020 Mike Talbot (Generator mods)
3 | *
4 | * The above copyright notice and this permission notice shall be included in all
5 | * copies or substantial portions of the Software.
6 | *
7 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
13 | * SOFTWARE.
14 | */
15 | import { Tokenizer } from "./tokenizer";
16 | import { AST } from "./ast";
17 | import { ExprType } from "./expression";
18 | import { TokenType } from "./token";
19 | import { yielder } from "./yielder";
20 |
21 | export class ASTParser {
22 | constructor(ast) {
23 | this.ast = ast;
24 | }
25 |
26 | *getJson() {
27 | return yield* this.handleValue(this.ast);
28 | }
29 |
30 | *handleJson(astNode) {
31 | if (astNode.type !== ExprType.Json) {
32 | throw new Error("[parse AST error] unexpected node type, expect Json");
33 | }
34 |
35 | let output;
36 | let node = astNode.childNodeList[0];
37 | if (node.type === ExprType.Array) {
38 | output = [];
39 | for (let item of node.childNodeList) {
40 | output.push(yield* this.handleValue(item.value));
41 | }
42 | } else if (node.type === ExprType.Object) {
43 | output = {};
44 | for (let item of node.childNodeList) {
45 | output[item.propName] = yield* this.handleValue(
46 | item.childNodeList[0].value
47 | );
48 | }
49 | } else {
50 | throw new Error("[parse AST error] unexpected second node type");
51 | }
52 | return output;
53 | }
54 |
55 | *handleValue(astNode) {
56 | if (yielder()) yield;
57 | let token;
58 | switch (astNode.type) {
59 | case TokenType.Null:
60 | return null;
61 | case TokenType.Boolean:
62 | token = astNode.tokens[0].text;
63 | return token === "true";
64 | case TokenType.Number:
65 | let num = +astNode.tokens[0].text;
66 | return num;
67 | case TokenType.String:
68 | return astNode.tokens[0].text.slice(1, -1);
69 | case ExprType.Json:
70 | return yield* this.handleJson(astNode);
71 | default:
72 | throw new Error(
73 | "[parse AST error] unexpected node type, expect a valid Value node"
74 | );
75 | }
76 | }
77 | }
78 |
79 | export function* parse(jsonString) {
80 | const tokenizer = new Tokenizer();
81 | const tokens = yield* tokenizer.tokenize(jsonString);
82 | const astInst = new AST(tokens);
83 | const ast = yield* astInst.buildTree();
84 | const astParser = new ASTParser(ast);
85 | return yield* astParser.getJson();
86 | }
87 |
--------------------------------------------------------------------------------
/dist/es6/yastjson/lib/token.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2020 5u9ar (zhuyingda)
3 | *
4 | * The above copyright notice and this permission notice shall be included in all
5 | * copies or substantial portions of the Software.
6 | *
7 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
13 | * SOFTWARE.
14 | */
15 | export const TokenType = {
16 | LeftBrace: "{",
17 | RightBrace: "}",
18 | LeftBracket: "l",
19 | RightBracket: "r",
20 | Comma: "c",
21 | Colon: "n",
22 | Null: "0",
23 | Boolean: "t",
24 | Number: "n",
25 | String: "s",
26 | };
27 |
--------------------------------------------------------------------------------
/dist/es6/yastjson/lib/yielder.js:
--------------------------------------------------------------------------------
1 | let yieldCount = 0;
2 | export function yielder() {
3 | if (yieldCount++ > 100) {
4 | yieldCount = 0;
5 | return true;
6 | }
7 | return false;
8 | }
9 |
--------------------------------------------------------------------------------
/dist/every.js:
--------------------------------------------------------------------------------
1 | "use strict";var _regeneratorRuntime2=require("@babel/runtime/regenerator"),_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.every=every;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_forEach=require("./for-each"),_arrayUtilities=require("./array-utilities"),_marked=_regeneratorRuntime2.mark(every);function every(a,b){var c;return _regenerator.default.wrap(function(d){for(;;)switch(d.prev=d.next){case 0:return c=!0,d.delegateYield((0,_forEach.forEach)(a,_regenerator.default.mark(function d(e,f){return _regenerator.default.wrap(function(d){for(;;)switch(d.prev=d.next){case 0:return d.delegateYield(b(e,f,a),"t0",1);case 1:if(d.t0){d.next=4;break}return c=!1,d.abrupt("return",(0,_arrayUtilities.exitWith)(!1));case 4:case"end":return d.stop();}},d)})),"t0",2);case 2:return d.abrupt("return",c);case 3:case"end":return d.stop();}},_marked)}
--------------------------------------------------------------------------------
/dist/filter-async.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.filterAsync=void 0;var _asyncWrapperUtils=require("./async-wrapper-utils"),_filter=require("./filter"),filterAsync=(0,_asyncWrapperUtils.wrapAsPromiseAndYieldFn)(_filter.filter);exports.filterAsync=filterAsync;
--------------------------------------------------------------------------------
/dist/filter.js:
--------------------------------------------------------------------------------
1 | "use strict";var _regeneratorRuntime2=require("@babel/runtime/regenerator"),_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.filter=filter;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_isObject=require("./is-object"),_forEach=require("./for-each"),_marked=_regeneratorRuntime2.mark(filter);function filter(a,b){var c,d;return _regenerator.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(!(0,_isObject.isObject)(a)){e.next=6;break}return c={},e.delegateYield((0,_forEach.forEach)(a,_regenerator.default.mark(function a(d,e,f){return _regenerator.default.wrap(function(a){for(;;)switch(a.prev=a.next){case 0:return a.delegateYield(b(d,e,f),"t0",1);case 1:if(!a.t0){a.next=3;break}c[e]=d;case 3:case"end":return a.stop();}},a)})),"t0",3);case 3:return e.abrupt("return",c);case 6:return d=[],e.delegateYield((0,_forEach.forEach)(a,_regenerator.default.mark(function a(c,e,f){return _regenerator.default.wrap(function(a){for(;;)switch(a.prev=a.next){case 0:return a.delegateYield(b(c,e,f),"t0",1);case 1:if(!a.t0){a.next=3;break}d.push(c);case 3:case"end":return a.stop();}},a)})),"t1",8);case 8:return e.abrupt("return",d);case 9:case"end":return e.stop();}},_marked)}
--------------------------------------------------------------------------------
/dist/find-async.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findAsync=void 0;var _asyncWrapperUtils=require("./async-wrapper-utils"),_find=require("./find"),findAsync=(0,_asyncWrapperUtils.wrapAsPromiseAndYieldFn)(_find.find);exports.findAsync=findAsync;
--------------------------------------------------------------------------------
/dist/find-index-async.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findIndexAsync=void 0;var _asyncWrapperUtils=require("./async-wrapper-utils"),_findIndex=require("./find-index"),findIndexAsync=(0,_asyncWrapperUtils.wrapAsPromiseAndYieldFn)(_findIndex.findIndex);exports.findIndexAsync=findIndexAsync;
--------------------------------------------------------------------------------
/dist/find-index.js:
--------------------------------------------------------------------------------
1 | "use strict";var _regeneratorRuntime2=require("@babel/runtime/regenerator"),_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.findIndex=findIndex;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_forEach=require("./for-each"),_arrayUtilities=require("./array-utilities"),_marked=_regeneratorRuntime2.mark(findIndex);function findIndex(a,b,c){var d;return _regenerator.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return d=-1,e.delegateYield((0,_forEach.forEach)(a,_regenerator.default.mark(function c(e,f){var g;return _regenerator.default.wrap(function(c){for(;;)switch(c.prev=c.next){case 0:return c.delegateYield(b(e,f,a),"t0",1);case 1:if(g=c.t0,!g){c.next=5;break}return d=f,c.abrupt("return",(0,_arrayUtilities.exitWith)(f));case 5:case"end":return c.stop();}},c)}),c),"t0",2);case 2:return e.abrupt("return",d);case 3:case"end":return e.stop();}},_marked)}
--------------------------------------------------------------------------------
/dist/find.js:
--------------------------------------------------------------------------------
1 | "use strict";var _regeneratorRuntime2=require("@babel/runtime/regenerator"),_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.find=find;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_forEach=require("./for-each"),_arrayUtilities=require("./array-utilities"),_marked=_regeneratorRuntime2.mark(find);function find(a,b,c){var d;return _regenerator.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return d=void 0,e.delegateYield((0,_forEach.forEach)(a,_regenerator.default.mark(function c(e,f){var g;return _regenerator.default.wrap(function(c){for(;;)switch(c.prev=c.next){case 0:return c.delegateYield(b(e,f,a),"t0",1);case 1:if(g=c.t0,!g){c.next=5;break}return d=e,c.abrupt("return",(0,_arrayUtilities.exitWith)(e));case 5:case"end":return c.stop();}},c)}),c),"t0",2);case 2:return e.abrupt("return",d);case 3:case"end":return e.stop();}},_marked)}
--------------------------------------------------------------------------------
/dist/for-each-async.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.forEachAsync=void 0;var _asyncWrapperUtils=require("./async-wrapper-utils"),_forEach=require("./for-each"),forEachAsync=(0,_asyncWrapperUtils.wrapAsPromiseAndYieldFn)(_forEach.forEach);exports.forEachAsync=forEachAsync;
--------------------------------------------------------------------------------
/dist/for-each.js:
--------------------------------------------------------------------------------
1 | "use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.forEach=forEach;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_isObject=require("./is-object"),_arrayUtilities=require("./array-utilities"),_marked=_regenerator.default.mark(forEach);function forEach(a,b,c){var d,e,f,g,h,i;return _regenerator.default.wrap(function(j){for(;;)switch(j.prev=j.next){case 0:if(!(0,_isObject.isObject)(a)){j.next=16;break}d=!c,j.t0=_regenerator.default.keys(a);case 3:if((j.t1=j.t0()).done){j.next=14;break}if(e=j.t1.value,d||(d=e===c),!d){j.next=12;break}if(!Object.prototype.hasOwnProperty.call(a,e)){j.next=12;break}return j.delegateYield(b(a[e],e,a),"t2",9);case 9:if(f=j.t2,!(f&&f[_arrayUtilities.doReturn])){j.next=12;break}return j.abrupt("return",f.value);case 12:j.next=3;break;case 14:j.next=25;break;case 16:g=c||0,h=a.length;case 17:if(!(g=o.length?{done:!0}:{done:!1,value:o[c++]}},e:function e(a){throw a},f:d}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var e,f=!0,g=!1;return{s:function s(){b=o[Symbol.iterator]()},n:function n(){var a=b.next();return f=a.done,a},e:function e(a){g=!0,e=a},f:function f(){try{f||null==b.return||b.return()}finally{if(g)throw e}}}}function _unsupportedIterableToArray(o,a){if(o){if("string"==typeof o)return _arrayLikeToArray(o,a);var n=Object.prototype.toString.call(o).slice(8,-1);return"Object"===n&&o.constructor&&(n=o.constructor.name),"Map"===n||"Set"===n?Array.from(o):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(o,a):void 0}}function _arrayLikeToArray(a,b){(null==b||b>a.length)&&(b=a.length);for(var c=0,d=Array(b);c=o.length?{done:!0}:{done:!1,value:o[c++]}},e:function e(a){throw a},f:d}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var e,f=!0,g=!1;return{s:function s(){b=o[Symbol.iterator]()},n:function n(){var a=b.next();return f=a.done,a},e:function e(a){g=!0,e=a},f:function f(){try{f||null==b.return||b.return()}finally{if(g)throw e}}}}function _unsupportedIterableToArray(o,a){if(o){if("string"==typeof o)return _arrayLikeToArray(o,a);var n=Object.prototype.toString.call(o).slice(8,-1);return"Object"===n&&o.constructor&&(n=o.constructor.name),"Map"===n||"Set"===n?Array.from(o):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(o,a):void 0}}function _arrayLikeToArray(a,b){(null==b||b>a.length)&&(b=a.length);for(var c=0,d=Array(b);ci)){a.next=29;break}return a.t0=k,a.next=14,m;case 14:if(a.t1=a.sent,o=a.t0.next.call(a.t0,a.t1),p=o.value,q=o.done,m=void 0,!q){a.next=22;break}return f(p),a.abrupt("return");case 22:if(!0!==p){a.next=26;break}return a.abrupt("break",29);case 26:"number"==typeof p?(i=+p,isNaN(i)&&(i=minRemainingTime)):p&&p.then&&(m=p);case 27:a.next=10;break;case 29:a.next=36;break;case 31:return a.prev=31,a.t2=a["catch"](9),console.error(a.t2),g(a.t2),a.abrupt("return");case 36:(0,_useInternalEngine.request)(h),c&&(l=setTimeout(j,c));case 38:return a.prev=38,n=!1,a.finish(38);case 41:case"end":return a.stop();}},a,null,[[2,,38,41],[9,31]])})),i.apply(this,arguments)}function j(){var a=Date.now();h({timeout:!0,timeRemaining:function timeRemaining(){return 12.5-(Date.now()-a)}})}e=f;var k=a.next?a:a();(0,_useInternalEngine.request)(h);var l=0,m=void 0,n=!1});return f.terminate=function(a){d=!0,e&&e(a)},f}var _default=run;exports.default=_default;
--------------------------------------------------------------------------------
/dist/singleton.js:
--------------------------------------------------------------------------------
1 | "use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");var _run=_interopRequireDefault(require("./run"));Object.defineProperty(exports,"__esModule",{value:!0}),exports.singleton=singleton;function singleton(a,b){var c=null,d=[],e=function(){return c&&(d.forEach(function(a){return a.terminate()}),d=[],c.terminate(b)),c=e._promise=(0,_run.default)(a.apply(void 0,arguments))};return e.join=function(a){return d.push(a),a},e}
--------------------------------------------------------------------------------
/dist/some-async.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.someAsync=void 0;var _asyncWrapperUtils=require("./async-wrapper-utils"),_some=require("./some"),someAsync=(0,_asyncWrapperUtils.wrapAsPromiseAndYieldFn)(_some.some);exports.someAsync=someAsync;
--------------------------------------------------------------------------------
/dist/some.js:
--------------------------------------------------------------------------------
1 | "use strict";var _regeneratorRuntime2=require("@babel/runtime/regenerator"),_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.some=some;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_forEach=require("./for-each"),_arrayUtilities=require("./array-utilities"),_marked=_regeneratorRuntime2.mark(some);function some(a,b){var c;return _regenerator.default.wrap(function(d){for(;;)switch(d.prev=d.next){case 0:return c=!1,d.delegateYield((0,_forEach.forEach)(a,_regenerator.default.mark(function d(e,f){return _regenerator.default.wrap(function(d){for(;;)switch(d.prev=d.next){case 0:return d.delegateYield(b(e,f,a),"t0",1);case 1:if(!d.t0){d.next=4;break}return c=!0,d.abrupt("return",(0,_arrayUtilities.exitWith)(!0));case 4:case"end":return d.stop();}},d)})),"t0",2);case 2:return d.abrupt("return",c);case 3:case"end":return d.stop();}},_marked)}
--------------------------------------------------------------------------------
/dist/sort-async.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.sortAsync=void 0;var _wrappers=require("./wrappers"),_timsort=require("./timsort"),sortAsync=(0,_wrappers.wrapAsPromise)(_timsort.sort);exports.sortAsync=sortAsync;
--------------------------------------------------------------------------------
/dist/tap.js:
--------------------------------------------------------------------------------
1 | "use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tap=tap;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")),_run=_interopRequireDefault(require("./run"));function tap(a){return function(){var b=(0,_asyncToGenerator2.default)(_regenerator.default.mark(function b(c){var d;return _regenerator.default.wrap(function(b){for(;;)switch(b.prev=b.next){case 0:if(d=a.call(this,c),!d){b.next=10;break}if(!d.next){b.next=7;break}return b.next=5,(0,_run.default)(d);case 5:b.next=10;break;case 7:if(!d.then){b.next=10;break}return b.next=10,d;case 10:return b.abrupt("return",c);case 11:case"end":return b.stop();}},b,this)}));return function(){return b.apply(this,arguments)}}()}
--------------------------------------------------------------------------------
/dist/unique-by-async.js:
--------------------------------------------------------------------------------
1 | "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.uniqueByAsync=void 0;var _asyncWrapperUtils=require("./async-wrapper-utils"),_uniqueBy=require("./unique-by"),uniqueByAsync=(0,_asyncWrapperUtils.wrapAsPromiseAndYieldFn)(_uniqueBy.uniqueBy);exports.uniqueByAsync=uniqueByAsync;
--------------------------------------------------------------------------------
/dist/unique-by.js:
--------------------------------------------------------------------------------
1 | "use strict";var _regeneratorRuntime2=require("@babel/runtime/regenerator"),_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.uniqueBy=uniqueBy;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator")),_marked=_regeneratorRuntime2.mark(uniqueBy);function _createForOfIteratorHelper(o,a){var b;if("undefined"==typeof Symbol||null==o[Symbol.iterator]){if(Array.isArray(o)||(b=_unsupportedIterableToArray(o))||a&&o&&"number"==typeof o.length){b&&(o=b);var c=0,d=function(){};return{s:d,n:function n(){return c>=o.length?{done:!0}:{done:!1,value:o[c++]}},e:function e(a){throw a},f:d}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var e,f=!0,g=!1;return{s:function s(){b=o[Symbol.iterator]()},n:function n(){var a=b.next();return f=a.done,a},e:function e(a){g=!0,e=a},f:function f(){try{f||null==b.return||b.return()}finally{if(g)throw e}}}}function _unsupportedIterableToArray(o,a){if(o){if("string"==typeof o)return _arrayLikeToArray(o,a);var n=Object.prototype.toString.call(o).slice(8,-1);return"Object"===n&&o.constructor&&(n=o.constructor.name),"Map"===n||"Set"===n?Array.from(o):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(o,a):void 0}}function _arrayLikeToArray(a,b){(null==b||b>a.length)&&(b=a.length);for(var c=0,d=Array(b);c=o.length?{done:!0}:{done:!1,value:o[c++]}},e:function e(a){throw a},f:d}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var e,f=!0,g=!1;return{s:function s(){b=o[Symbol.iterator]()},n:function n(){var a=b.next();return f=a.done,a},e:function e(a){g=!0,e=a},f:function f(){try{f||null==b.return||b.return()}finally{if(g)throw e}}}}function _unsupportedIterableToArray(o,a){if(o){if("string"==typeof o)return _arrayLikeToArray(o,a);var n=Object.prototype.toString.call(o).slice(8,-1);return"Object"===n&&o.constructor&&(n=o.constructor.name),"Map"===n||"Set"===n?Array.from(o):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(o,a):void 0}}function _arrayLikeToArray(a,b){(null==b||b>a.length)&&(b=a.length);for(var c=0,d=Array(b);cb.length?function(){for(var d=arguments.length,e=Array(d),f=0;f ul > li > ul li").forEach(function(parent) {
5 | parent.style.display = "none";
6 | });
7 |
8 | //only current page (if it exists) should be opened
9 | var file = window.location.pathname.split("/").pop().replace(/\.html/, '');
10 | document.querySelectorAll("nav > ul > li > a").forEach(function(parent) {
11 | var href = parent.attributes.href.value.replace(/\.html/, '');
12 | if (file === href) {
13 | parent.parentNode.querySelectorAll("ul li").forEach(function(elem) {
14 | elem.style.display = "block";
15 | });
16 | }
17 | });
18 | }
19 |
20 | hideAllButCurrent();
--------------------------------------------------------------------------------
/docs/scripts/linenumber.js:
--------------------------------------------------------------------------------
1 | /*global document */
2 | (function() {
3 | var source = document.getElementsByClassName('prettyprint source linenums');
4 | var i = 0;
5 | var lineNumber = 0;
6 | var lineId;
7 | var lines;
8 | var totalLines;
9 | var anchorHash;
10 |
11 | if (source && source[0]) {
12 | anchorHash = document.location.hash.substring(1);
13 | lines = source[0].getElementsByTagName('li');
14 | totalLines = lines.length;
15 |
16 | for (; i < totalLines; i++) {
17 | lineNumber++;
18 | lineId = 'line' + lineNumber;
19 | lines[i].id = lineId;
20 | if (lineId === anchorHash) {
21 | lines[i].className += ' selected';
22 | }
23 | }
24 | }
25 | })();
26 |
--------------------------------------------------------------------------------
/docs/scripts/nav.js:
--------------------------------------------------------------------------------
1 | function scrollToNavItem() {
2 | var path = window.location.href.split('/').pop().replace(/\.html/, '');
3 | document.querySelectorAll('nav a').forEach(function(link) {
4 | var href = link.attributes.href.value.replace(/\.html/, '');
5 | if (path === href) {
6 | link.scrollIntoView({block: 'center'});
7 | return;
8 | }
9 | })
10 | }
11 |
12 | scrollToNavItem();
13 |
--------------------------------------------------------------------------------
/docs/scripts/polyfill.js:
--------------------------------------------------------------------------------
1 | //IE Fix, src: https://www.reddit.com/r/programminghorror/comments/6abmcr/nodelist_lacks_foreach_in_internet_explorer/
2 | if (typeof(NodeList.prototype.forEach)!==typeof(alert)){
3 | NodeList.prototype.forEach=Array.prototype.forEach;
4 | }
--------------------------------------------------------------------------------
/docs/scripts/prettify/lang-css.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
3 |
--------------------------------------------------------------------------------
/docs/scripts/search.js:
--------------------------------------------------------------------------------
1 |
2 | var searchAttr = 'data-search-mode';
3 | function contains(a,m){
4 | return (a.textContent || a.innerText || "").toUpperCase().indexOf(m) !== -1;
5 | };
6 |
7 | //on search
8 | document.getElementById("nav-search").addEventListener("keyup", function(event) {
9 | var search = this.value.toUpperCase();
10 |
11 | if (!search) {
12 | //no search, show all results
13 | document.documentElement.removeAttribute(searchAttr);
14 |
15 | document.querySelectorAll("nav > ul > li:not(.level-hide)").forEach(function(elem) {
16 | elem.style.display = "block";
17 | });
18 |
19 | if (typeof hideAllButCurrent === "function"){
20 | //let's do what ever collapse wants to do
21 | hideAllButCurrent();
22 | } else {
23 | //menu by default should be opened
24 | document.querySelectorAll("nav > ul > li > ul li").forEach(function(elem) {
25 | elem.style.display = "block";
26 | });
27 | }
28 | } else {
29 | //we are searching
30 | document.documentElement.setAttribute(searchAttr, '');
31 |
32 | //show all parents
33 | document.querySelectorAll("nav > ul > li").forEach(function(elem) {
34 | elem.style.display = "block";
35 | });
36 | //hide all results
37 | document.querySelectorAll("nav > ul > li > ul li").forEach(function(elem) {
38 | elem.style.display = "none";
39 | });
40 | //show results matching filter
41 | document.querySelectorAll("nav > ul > li > ul a").forEach(function(elem) {
42 | if (!contains(elem.parentNode, search)) {
43 | return;
44 | }
45 | elem.parentNode.style.display = "block";
46 | });
47 | //hide parents without children
48 | document.querySelectorAll("nav > ul > li").forEach(function(parent) {
49 | var countSearchA = 0;
50 | parent.querySelectorAll("a").forEach(function(elem) {
51 | if (contains(elem, search)) {
52 | countSearchA++;
53 | }
54 | });
55 |
56 | var countUl = 0;
57 | var countUlVisible = 0;
58 | parent.querySelectorAll("ul").forEach(function(ulP) {
59 | // count all elements that match the search
60 | if (contains(ulP, search)) {
61 | countUl++;
62 | }
63 |
64 | // count all visible elements
65 | var children = ulP.children
66 | for (i=0; i0.2%",
66 | "not dead",
67 | "IE 11",
68 | "not op_mini all"
69 | ],
70 | "development": [
71 | "last 1 chrome version",
72 | "last 1 firefox version",
73 | "last 1 safari version"
74 | ]
75 | },
76 | "peerDependencies": {
77 | "@babel/runtime": ">=7.4.8"
78 | }
79 | }
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/scripts/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | rm -rf dist
4 | NODE_ENV=production babel src/component --ignore "__tests__","**/*.spec.js","**/*.test.js","__snapshots__" --out-dir dist
5 | cp -r src/component dist/es6
6 | rm -rf dist/es6/yastjson/test
7 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .info-list {
17 | position: absolute;
18 | padding: 4px;
19 | background: #0000001f;
20 | bottom: 15px;
21 | text-align: left;
22 | font-size: 16px;
23 | width: 500px;
24 | }
25 |
26 | .App-header {
27 | background-color: #282c34;
28 | min-height: 100vh;
29 | display: flex;
30 | flex-direction: column;
31 | align-items: center;
32 | justify-content: center;
33 | font-size: calc(10px + 2vmin);
34 | color: white;
35 | }
36 |
37 | .App-link {
38 | color: #61dafb;
39 | }
40 |
41 | @keyframes App-logo-spin {
42 | from {
43 | transform: rotate(0deg);
44 | }
45 | to {
46 | transform: rotate(360deg);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/src/component/append-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromise} from './wrappers'
2 | import {append} from './append'
3 |
4 | /**
5 | * Appends one array to another asynchronously
6 | * @function appendAsync
7 | * @param {Array} destination
8 | * @param {Array} source
9 | * @returns {Promise.} a promise for destination after appending
10 | */
11 | export const appendAsync = wrapAsPromise(append)
12 |
--------------------------------------------------------------------------------
/src/component/append.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {yielding} from './wrappers'
3 |
4 | /**
5 | * Appends one array to another
6 | * @generator
7 | * @param {Array} array1 - the destination
8 | * @param {Array} array2 - the source
9 | * @returns {Generator<*, Array, *>} returns array1
10 | * @example
11 | *
12 | * // Updates array1
13 | * yield * append(array1, array2)
14 | */
15 | export function* append(array1, array2) {
16 | const l = array1.length
17 | yield true
18 | array1.length += array2.length
19 | yield
20 | yield* forEach(
21 | array2,
22 | yielding((a, i) => (array1[i + l] = a))
23 | )
24 |
25 | return array1
26 | }
27 |
--------------------------------------------------------------------------------
/src/component/array-utilities.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @callback Filter
3 | * @param {any} element
4 | * @param {number} index
5 | * @param {Array} collection
6 | * @returns {Generator} a generator for a value of true if included in the filter
7 | */
8 |
9 | /**
10 | * @callback Map
11 | * @param {any} element
12 | * @param {number} index
13 | * @param {Array} collection
14 | * @returns {any} updated item
15 | */
16 |
17 | /**
18 | * @callback Reduce
19 | * @param {any} accumulator
20 | * @param {any} element
21 | * @param {number} index
22 | * @param {Array} collection
23 | * @returns {any} updated value
24 | */
25 |
26 | /**
27 | * @callback Process
28 | * @param {any} value - the value being processed
29 | * @param {number|string} key - the key or index of the value
30 | * @param {Array} collection - the collection being iterated
31 | */
32 |
33 | export const doReturn = Symbol('return')
34 |
35 | export function exitWith(value) {
36 | return {[doReturn]: true, value}
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/src/component/async-array-wrappers.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {every} from './every'
3 |
4 | /**
5 | * Asynchronously check if every element in an array matches
6 | * a predicate
7 | * @function everyAsync
8 | * @param {Array} array
9 | * @param {Filter} fn
10 | * @returns {Promise.} promise for true if all items matched the filter
11 | */
12 | export const everyAsync = wrapAsPromiseAndYieldFn(every)
13 |
14 | /**
15 | * @callback SortFunction
16 | * @param {any} item1
17 | * @param {any} item2
18 | * @returns < 0 if item 2 is bigger than item 1, === 0 if they are the same else > 0
19 | */
20 |
21 | /**
22 | * @callback ExtractFunction
23 | * @param {any} item1
24 | * @returns {any} the value to sort item 1 by
25 | */
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/component/async-json-wrappers.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromise} from './wrappers'
2 | import {parse} from './yastjson/lib/parse'
3 | import {stringify} from './json'
4 |
5 | /**
6 | * Asynchronously stringify data into JSON
7 | * @function
8 | * @name stringifyAsync
9 | * @param {any} data - Object to store
10 | * @returns {Promise.} a Promise for the JSON representation of data
11 | */
12 | export const stringifyAsync = wrapAsPromise(stringify)
13 | /**
14 | * Asynchronously parse JSON into an object
15 | * @function parseAsync
16 | * @param {String} json - the JSON to be parsed
17 | * @returns {Promise.} a Promise for the parsed JSON
18 | */
19 | export const parseAsync = wrapAsPromise(parse)
20 |
--------------------------------------------------------------------------------
/src/component/async-wrapper-utils.js:
--------------------------------------------------------------------------------
1 | import {yielding} from './wrappers'
2 | import run from './run'
3 | import {call} from './call'
4 |
5 | /**
6 | * Create a promised function
7 | * @param {Function} fn
8 | * @returns {Function}
9 | */
10 | export function wrapAsPromiseAndYieldFn(fn) {
11 | const result = function (array, processor, ...params) {
12 | return run(fn(array, yielding(processor), ...params))
13 | }
14 | result.with = function (...params) {
15 | return call(result, ...params)
16 | }
17 | return result
18 | }
19 |
--------------------------------------------------------------------------------
/src/component/async-wrappers.js:
--------------------------------------------------------------------------------
1 | export * from './async-array-wrappers'
2 | export * from './async-compression-wrappers'
3 | export * from './async-json-wrappers'
4 | export {sortAsync} from './sort-async'
5 | export {findAsync} from './find-async'
6 | export {findIndexAsync} from './find-index-async'
7 | export {mapAsync} from './map-async'
8 | export {filterAsync} from './filter-async'
9 | export {reduceAsync} from './reduce-async'
10 | export {appendAsync} from './append-async'
11 | export {concatAsync} from './concat-async'
12 | export {forEachAsync} from './for-each-async'
13 | export {someAsync} from './some-async'
14 | export {includesAsync} from './includes-async'
15 | export {indexOfAsync} from './index-of-async'
16 | export {lastIndexOfAsync} from './last-index-of-async'
17 | export {keyByAsync} from './key-by-async'
18 | export {groupByAsync} from './group-by-async'
19 | export {uniqueByAsync} from './unique-by-async'
20 |
--------------------------------------------------------------------------------
/src/component/branch.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Branches a pipeline by starting another "continuation" with
5 | * the current parameters. Starts a function but the pipeline
6 | * continues immediately creating two execution contexts
7 | * @param {Function} fn - the function to start - can be async or generator
8 | */
9 | export function branch(fn) {
10 | return function (params) {
11 | let result = fn.call(this, params)
12 | if (result) {
13 | if (result.next) {
14 | run(result).catch(console.error)
15 | } else if (result.then) {
16 | result.catch(console.error)
17 | }
18 | }
19 | return params
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/component/call.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Create a version of a function with its end
3 | * parameters supplied
4 | * @param {Function|GeneratorFunction|AsyncFunction} fn - the function to configure
5 | * @param {...any[]} config - the additional parameters to pass
6 | * @returns {Function}
7 | */
8 | export function call(fn, ...config) {
9 | return function (...params) {
10 | return fn.apply(this, [...params, ...config])
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/component/compose.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Create a function that executes a pipeline of
5 | * functions asynchronously, the function executes the list in
6 | * REVERSE order, allowing you to "compose on" a new function
7 | * at the head of the chain
8 | * @param {...(Function|Promise|Array<(Promise|Function|GeneratorFunction|AsyncFunction)>|GeneratorFunction|AsyncFunction)} fns - the pipeline to execute
9 | * @returns {AsyncFunction} an async function to execute the pipeline
10 | */
11 | export function compose(...fns) {
12 | return async function (params) {
13 | let result = params
14 |
15 | let list = fns.flat(Infinity)
16 | for (let i = list.length - 1; i >= 0; i--) {
17 | let fn = list[i]
18 | if (!fn) continue
19 | let nextResult = fn.call(this, result)
20 | if (nextResult) {
21 | if (nextResult.next) {
22 | result = await run(nextResult)
23 | } else if (nextResult.then) {
24 | result = await nextResult
25 | } else {
26 | result = nextResult
27 | }
28 | }
29 | }
30 | return result
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/component/concat-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromise} from './wrappers'
2 | import {concat} from './concat'
3 |
4 | /**
5 | * Concatenates 2 arrays into a new array
6 | * @function concatAsync
7 | * @param {Array} array1
8 | * @param {Array} array2
9 | * @returns {Promise.} a promise for combined array
10 | */
11 | export const concatAsync = wrapAsPromise(concat)
12 |
--------------------------------------------------------------------------------
/src/component/concat.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {yielding} from './wrappers'
3 |
4 | /**
5 | * Concatenate two arrays into a new array
6 | * @generator
7 | * @param {Array} array1
8 | * @param {Array} array2
9 | * @returns {Generator<*, Array, *>} the concatenated arrays
10 | * @example
11 | *
12 | * const concatenated = yield * concat(array1, array2)
13 | */
14 | export function* concat(array1, array2) {
15 | yield true
16 | const result = new Array(array1.length + array2.length)
17 | yield
18 | const l = array1.length
19 | yield* forEach(
20 | array1,
21 | yielding((a, i) => (result[i] = a))
22 | )
23 | yield* forEach(
24 | array2,
25 | yielding((a, i) => (result[i + l] = a))
26 | )
27 | return result
28 | }
29 |
--------------------------------------------------------------------------------
/src/component/coroutines.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * A coroutine to be run during the gaps in other processing and animation.
4 | *
5 | *
6 | * The coroutine should yield regularly to do a time check. A plain yield will cause
7 | * a check against the standard time remaining specified when running. yield {number} will
8 | * check that number milliseconds are available and yield true will abandon any more
9 | * processing on the current frame.
10 | *
11 | * @callback Coroutine
12 | * @generator
13 | * @yields {number} either undefined to perform a standard time remaining check, a number of milliseconds required for the next step or true if we should abandon the current frame
14 | * @returns the result of the function if any to be returned to the caller
15 | */
16 |
17 | /**
18 | * @typedef IteratorResult
19 | * @object
20 | * @property {any} [value] - the returned value
21 | * @property {boolean} done - whether the iterator is complete
22 | */
23 |
24 | /**
25 | * @interface Iterator
26 | */
27 |
28 | /**
29 | * Get the next value
30 | * @function
31 | * @name Iterator#next
32 | * @param {any} value - value to send to the coroutine
33 | * @returns {IteratorResult}
34 | */
35 |
36 | /**
37 | * A coroutine to be used in high priority to animate.
38 | *
39 | * Executing a yield will cause the routine to resume at the start
40 | * of the next frame.
41 | * @callback AnimationCoroutine
42 | * @generator
43 | * @returns the result of the function if any to be returned to the caller
44 | */
45 |
46 |
47 | /**
48 | * @callback GeneratorFunction
49 | * @generator
50 | * @param {...*} params - the parameters to pass
51 | * @returns {*} the result of the coroutine
52 | */
53 |
54 | /**
55 | * @callback AsyncFunction
56 | * @param {*} params - the parameters to pass
57 | * @async
58 | * @returns {*} result of calling the function
59 | */
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/component/every.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {exitWith} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @returns {Generator<*, boolean, *>} true if all of the collection items matched the filter
9 | * @example
10 | *
11 | * if(! yield * every(records, yielding(r=>r.valid))) return
12 | */
13 | export function* every(collection, fn) {
14 | let result = true
15 | yield* forEach(collection, function* (value, key) {
16 | if (!(yield* fn(value, key, collection))) {
17 | result = false
18 | return exitWith(false)
19 | }
20 | })
21 | return result
22 | }
23 |
--------------------------------------------------------------------------------
/src/component/filter-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {filter} from './filter'
3 |
4 | /**
5 | * Filters an array asynchronously
6 | * @function filterAsync
7 | * @param {Array} array
8 | * @param {Filter} filter
9 | * @returns {Promise.} promise for the filtered array
10 | */
11 | export const filterAsync = wrapAsPromiseAndYieldFn(filter)
12 |
--------------------------------------------------------------------------------
/src/component/filter.js:
--------------------------------------------------------------------------------
1 | import {isObject} from './is-object'
2 | import {forEach} from './for-each'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @returns {Generator<*, Object|Array, *>} collection of elements matching the filter
9 | * @example
10 | *
11 | * const filtered = yield * filter(array, yielding(v=>v.value > 1000, 100))
12 | */
13 | export function* filter(collection, fn) {
14 | if (isObject(collection)) {
15 | let result = {}
16 | yield* forEach(collection, function* (value, key, array) {
17 | if (yield* fn(value, key, array)) {
18 | result[key] = value
19 | }
20 | })
21 | return result
22 | } else {
23 | let result = []
24 | yield* forEach(collection, function* (value, key, array) {
25 | if (yield* fn(value, key, array)) {
26 | result.push(value)
27 | }
28 | })
29 | return result
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/component/find-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {find} from './find'
3 |
4 | /**
5 | * Finds an item in an array asynchronously
6 | * @function findAsync
7 | * @param {Array} array
8 | * @param {Filter} filter
9 | * @returns {Promise.} promise for the item found or null if no match
10 | */
11 | export const findAsync = wrapAsPromiseAndYieldFn(find)
12 |
--------------------------------------------------------------------------------
/src/component/find-index-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {findIndex} from './find-index'
3 |
4 | /**
5 | * Finds an item index in an array asynchronously
6 | * @function findIndexAsync
7 | * @param {Array} array
8 | * @param {Filter} filter
9 | * @returns {Promise.} promise for the index of the first item to pass the filter or -1
10 | */
11 | export const findIndexAsync = wrapAsPromiseAndYieldFn(findIndex)
12 |
--------------------------------------------------------------------------------
/src/component/find-index.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {exitWith} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @returns {Generator<*, number, *>} Index of matching element or -1
9 | * @example
10 | *
11 | * if(-1 === yield * findIndex(records, yielding(v=>v.id === '123')))
12 | * return
13 | */
14 | export function* findIndex(collection, fn, start) {
15 | let output = -1
16 | yield* forEach(
17 | collection,
18 | function* (value, key) {
19 | let result = yield* fn(value, key, collection)
20 | if (result) {
21 | output = key
22 | return exitWith(key)
23 | }
24 | },
25 | start
26 | )
27 | return output
28 | }
29 |
--------------------------------------------------------------------------------
/src/component/find.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {exitWith} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @param {any} [start] - the key to start at
9 | * @returns {Generator<*, *, *>} the first matching value in the collection or null
10 | * @example
11 | *
12 | * const record = yield * find(arrayOfRecords, yielding(v=>v.id === '1234'))
13 | */
14 | export function* find(collection, fn, start) {
15 | let output = undefined
16 | yield* forEach(
17 | collection,
18 | function* (value, key) {
19 | let result = yield* fn(value, key, collection)
20 | if (result) {
21 | output = value
22 | return exitWith(value)
23 | }
24 | },
25 | start
26 | )
27 | return output
28 | }
29 |
--------------------------------------------------------------------------------
/src/component/for-each-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {forEach} from './for-each'
3 |
4 | /**
5 | * Asynchronously loop over the elements of an array
6 | * @function forEachAsync
7 | * @param {Array} array
8 | * @param {Process} fn
9 | * @returns {Promise} promise for the end of the operation
10 | */
11 | export const forEachAsync = wrapAsPromiseAndYieldFn(forEach)
12 |
--------------------------------------------------------------------------------
/src/component/for-each.js:
--------------------------------------------------------------------------------
1 | import {isObject} from './is-object'
2 | import {doReturn} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Process} fn
8 | * @param {number|string} [start]
9 | * @returns {Generator<*, *, *>}
10 | * @example
11 | * // Loop over all keys/value pairs in an object
12 | * yield * forEach(object, yielding((value, key)=> { ... }))
13 | *
14 | * // Loop over all the values in an array
15 | * yield * forEach(array, generatorFunction)
16 | *
17 | * function * generatorFunction(value, index) {
18 | * let i = 0
19 | * while(i < 10000) {
20 | * doSomething(value)
21 | * if(i % 100 === 0) yield
22 | * }
23 | * }
24 | */
25 | export function* forEach(collection, fn, start) {
26 | if (isObject(collection)) {
27 | let started = !start
28 | for (let key in collection) {
29 | if (!started) {
30 | started = key === start
31 | }
32 | if (started) {
33 | if (Object.prototype.hasOwnProperty.call(collection, key)) {
34 | let result = yield* fn(collection[key], key, collection)
35 | if (result && result[doReturn]) return result.value
36 | }
37 | }
38 | }
39 | } else {
40 | for (let index = start || 0, length = collection.length; index < length; index++) {
41 | let result = yield* fn(collection[index], index, collection)
42 | if (result && result[doReturn]) return result.value
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/component/group-by-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {groupBy} from './group-by'
3 |
4 | /**
5 | * Promises the creation of an object composed of keys generated from the results
6 | * of running each element of collection thru then supplied function.
7 | * The corresponding value of each key is an collection of the elements responsible
8 | * for generating the key.
9 | *
10 | * @param {Array|Object} collection
11 | * @param {Map} fn
12 | * @returns {Promise<{}>}
13 | */
14 | export const groupByAsync = wrapAsPromiseAndYieldFn(groupBy)
15 |
--------------------------------------------------------------------------------
/src/component/group-by.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates an object composed of keys generated from the results
3 | * of running each element of collection thru then supplied function.
4 | * The corresponding value of each key is an collection of the elements responsible
5 | * for generating the key.
6 | *
7 | * @param {Array|Object} collection
8 | * @param {Map} fn
9 | * @returns {Generator<*, {}, *>} a generator for the new object
10 | * @example
11 | *
12 | * let groups = yield * groupBy(records, yielding(v=>v.category))
13 | *
14 | * ...
15 | *
16 | * console.log(groups['category1']) // -> [{id: 1, ...}, {id: 2, ...}]
17 | *
18 | */
19 | export function* groupBy(collection, fn) {
20 | let result = {}
21 | let index = 0
22 | for (let item of collection) {
23 | let key = yield* fn(item, index++, collection)
24 | const array = (result[key] = result[key] || [])
25 | array.push(item)
26 | }
27 | return result
28 | }
29 |
--------------------------------------------------------------------------------
/src/component/includes-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {includes} from './includes'
3 |
4 | /**
5 | * Returns a promise returning true if an array includes a value
6 | * @param array
7 | * @param value
8 | * @returns Promise
9 | * @example
10 | * if(await includesAsync(someArray, 'error')) {
11 | * ...
12 | * }
13 | */
14 | export const includesAsync = wrapAsPromiseAndYieldFn(includes)
15 |
--------------------------------------------------------------------------------
/src/component/includes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns true if an array includes a value
3 | * @param {Array} array
4 | * @param {any} value
5 | * @returns {Generator<*, boolean, *>}
6 | * @example
7 | *
8 | * prices = price * (yield * includes(items, yielding(v=>v.discount))) ? .4 : 1
9 | */
10 | export function* includes(array, value) {
11 | for (let i = 0, l = array.length; i < l; i++) {
12 | if (array[i] === value) return true
13 | if ((i & 63) === 0) yield
14 | }
15 | return false
16 | }
17 |
--------------------------------------------------------------------------------
/src/component/index-of-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {indexOf} from './index-of'
3 |
4 | /**
5 | * Returns a promise for the first index of an item in an array
6 | * @param array - the array to scan
7 | * @param value - the value to search for
8 | * @returns {Promise}
9 | */
10 | export const indexOfAsync = wrapAsPromiseAndYieldFn(indexOf)
11 |
--------------------------------------------------------------------------------
/src/component/index-of.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns a generator for an index of an item in an array
3 | * @param {Array} array - the array to scan
4 | * @param {*} value - the value to search for
5 | * @returns {Generator<*, number, *>}
6 | */
7 | export function* indexOf(array, value) {
8 | for (let i = 0, l = array.length; i < l; i++) {
9 | if (array[i] === value) return i
10 | if ((i & 63) === 0) yield
11 | }
12 | return -1
13 | }
14 |
--------------------------------------------------------------------------------
/src/component/is-object.js:
--------------------------------------------------------------------------------
1 | export function isObject(v) {
2 | return typeof v === 'object' && !Array.isArray(v)
3 | }
4 |
--------------------------------------------------------------------------------
/src/component/key-by-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {keyBy} from './key-by'
3 |
4 | /**
5 | * Promises the creation an object composed of keys generated from the results
6 | * of running each element of collection thru then supplied function.
7 | * The corresponding value of each key is the last element responsible
8 | * for generating the key.
9 | *
10 | * @param {Array|Object} collection
11 | * @param {Map} fn
12 | * @returns {Promise<{}>}
13 | */
14 | export const keyByAsync = wrapAsPromiseAndYieldFn(keyBy)
15 |
--------------------------------------------------------------------------------
/src/component/key-by.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 |
3 | /**
4 | * Creates an object composed of keys generated from the results
5 | * of running each element of collection thru then supplied function.
6 | * The corresponding value of each key is the last element responsible
7 | * for generating the key.
8 | *
9 | * @param {Array|Object} collection
10 | * @param {Map} fn
11 | * @returns {Generator<*, {}, *>} a generator for the new object
12 | * @example
13 | *
14 | * let lookup = yield * keyBy(records, yielding(r=>r.id))
15 | *
16 | * ...
17 | *
18 | * let row = lookup[id]
19 | *
20 | */
21 | export function* keyBy(collection, fn) {
22 | let result = {}
23 | yield* forEach(collection, function* (value, key) {
24 | let newKey = yield* fn(value, key, collection)
25 | result[newKey] = value
26 | })
27 | return result
28 | }
29 |
--------------------------------------------------------------------------------
/src/component/last-index-of-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {lastIndexOf} from './last-index-of'
3 |
4 | /**
5 | * Returns a promise for the last index of an item in an array
6 | * @param array - the array to scan
7 | * @param value - the value to search for
8 | * @returns {Promise}
9 | */
10 | export const lastIndexOfAsync = wrapAsPromiseAndYieldFn(lastIndexOf)
11 |
--------------------------------------------------------------------------------
/src/component/last-index-of.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns a generator for an index of an item in an array
3 | * @param {Array} array - the array to scan
4 | * @param {*} value - the value to search for
5 | * @returns {Generator<*, number, *>}
6 | * @example
7 | *
8 | * let last = yield * lastIndexOf(collection, record)
9 | *
10 | */
11 | export function* lastIndexOf(array, value) {
12 | for (let i = array.length - 1; i >= 0; i--) {
13 | if (array[i] === value) return i
14 | if ((i & 63) === 0) yield
15 | }
16 | return -1
17 | }
18 |
--------------------------------------------------------------------------------
/src/component/map-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {map} from './map'
3 |
4 | /**
5 | * Maps the contents of an array asynchronously
6 | * @function mapAsync
7 | * @param {Array} array
8 | * @param {Map} mapFn
9 | * @returns {Promise.} promise for the mapped array
10 | */
11 | export const mapAsync = wrapAsPromiseAndYieldFn(map)
12 |
--------------------------------------------------------------------------------
/src/component/map.js:
--------------------------------------------------------------------------------
1 | import {isObject} from './is-object'
2 | import {forEach} from './for-each'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Map} fn
8 | * @returns {Generator<*, Array|Object, *>} new collection of mapped values
9 | * @example
10 | *
11 | * const values = yield * map(array, yielding(v=>v ** 2))
12 | *
13 | */
14 | export function* map(collection, fn) {
15 | let result = isObject(collection) ? {} : []
16 | yield* forEach(collection, function* (value, key) {
17 | result[key] = yield* fn(value, key, collection)
18 | })
19 | return result
20 | }
21 |
--------------------------------------------------------------------------------
/src/component/pipe.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Create a function that executes a pipeline of
5 | * functions asynchronously
6 | * @param {...(Function|Promise|Array<(Promise|Function|GeneratorFunction|AsyncFunction)>|GeneratorFunction|AsyncFunction)} fns - the pipeline to execute
7 | * @returns {AsyncFunction} an async function to execute the pipeline
8 | */
9 | export function pipe(...fns) {
10 | return async function (params) {
11 | let result = params
12 | for (let fn of fns.flat(Infinity)) {
13 | if (!fn) continue
14 | let nextResult = fn.call(this, result)
15 | if (nextResult) {
16 | if (nextResult.next) {
17 | result = await run(nextResult)
18 | } else if (nextResult.then) {
19 | result = await nextResult
20 | } else {
21 | result = nextResult
22 | }
23 | }
24 | }
25 | return result
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/component/reduce-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {reduce} from './reduce'
3 |
4 | /**
5 | * Performs a reduce on an array asynchronously
6 | * @function reduceAsync
7 | * @param {Array} array
8 | * @param {Reduce} reduceFn
9 | * @param {any} initialValue
10 | * @returns {Promise.} a promise for the reduced value
11 | */
12 | export const reduceAsync = wrapAsPromiseAndYieldFn(reduce)
13 |
--------------------------------------------------------------------------------
/src/component/reduce.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 |
3 | /**
4 | * @param {Array|Object} target
5 | * @param {Reduce} fn
6 | * @param {any} [initial]
7 | * @returns {Generator<*, *, *>} The result of processing the reduction function on all
8 | * of the items in the target
9 | * @example
10 | *
11 | * async function sumAge(items) {
12 | * const output = await reduceAsync(items, (acc,cur)=>acc += cur.age, 0)
13 | * }
14 | */
15 | export function* reduce(target, fn, initial) {
16 | let result = initial !== undefined ? initial : target[0]
17 | let first = true
18 | yield* forEach(target, function* (item, key) {
19 | if (first && !initial) {
20 | result = item
21 | first = false
22 | } else {
23 | result = yield* fn(result, item, key, target)
24 | }
25 | })
26 | return result
27 | }
28 |
--------------------------------------------------------------------------------
/src/component/repeat.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Create a function that repeats a function multiple times
5 | * passing the output of each iteration as the input to the next
6 | * @param {Function} fn - the function to repeat
7 | * @param {Number} times - the number of times to repeat
8 | * @returns {AsyncFunction} - a async function that repeats the operation
9 | */
10 | export function repeat(fn, times) {
11 | return async function (params) {
12 | let result = params
13 | for (let i = 0; i < times; i++) {
14 | result = fn.call(this, result)
15 | if (result.next) {
16 | result = await run(result)
17 | } else if (result.then) {
18 | result = await result
19 | }
20 | }
21 | return result
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/component/singleton.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Creates a singleton executor of a generator function.
5 | * If the function is currently running it will be
6 | * terminated with the defaultValue and a new one started.
7 | *
8 | * This would often be used with a UI to cancel a previous calculation
9 | * and begin updates on a new one.
10 | *
11 | * @param {Function} fn - the generator function to wrap
12 | * @param {any} [defaultValue] - a value to be returned if the current execution is
13 | * terminated by a new one starting
14 | * @returns {function(...[*]): Promise} a function to execute the
15 | * generator and return the value
16 | * @example
17 | *
18 | * const job = singleton(function * (array, value) {
19 | * let output = []
20 | * for(let item of array) {
21 | * if(output.length % 100 === 0) yield
22 | * output.push(complexCalculation(array, value))
23 | * }
24 | * return output
25 | * }, [])
26 | *
27 | * function doSomething(array) {
28 | * job(array, 2002).then(console.log)
29 | * }
30 | *
31 | * doSomething(bigArray)
32 | * doSomething(otherArray) // -> console.log([]) from first one
33 | *
34 | */
35 | export function singleton(fn, defaultValue) {
36 | let promise = null
37 | let extraPromises = []
38 | let result = (...params) => {
39 | if (promise) {
40 | extraPromises.forEach(p => p.terminate())
41 | extraPromises = []
42 | promise.terminate(defaultValue)
43 | }
44 | return promise = result._promise = run(fn(...params))
45 | }
46 | result.join = function (promise) {
47 | extraPromises.push(promise)
48 | return promise
49 | }
50 | return result
51 | }
52 |
--------------------------------------------------------------------------------
/src/component/some-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {some} from './some'
3 |
4 | /**
5 | * Asynchronously apply an array some operation
6 | * returning a promise for true if at least
7 | * one item matches
8 | * @function someAsync
9 | * @param {Array} array
10 | * @param {Filter} fn
11 | * @returns {Promise.} promise for true if at least one item matched the filter
12 | */
13 | export const someAsync = wrapAsPromiseAndYieldFn(some)
14 |
--------------------------------------------------------------------------------
/src/component/some.js:
--------------------------------------------------------------------------------
1 | import {forEach} from './for-each'
2 | import {exitWith} from './array-utilities'
3 |
4 | /**
5 | * @generator
6 | * @param {Array|Object} collection
7 | * @param {Filter} fn
8 | * @returns {Generator<*, boolean, *>} true if at least one item matched the filter
9 | * @example
10 | *
11 | *
12 | * if(yield * some(collection, yielding(v=>v > 2000)) {
13 | * ...
14 | * }
15 | */
16 | export function* some(collection, fn) {
17 | let result = false
18 | yield* forEach(collection, function* (value, key) {
19 | if (yield* fn(value, key, collection)) {
20 | result = true
21 | return exitWith(true)
22 | }
23 | })
24 | return result
25 | }
26 |
--------------------------------------------------------------------------------
/src/component/sort-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromise} from './wrappers'
2 | import {sort} from './timsort'
3 |
4 | /**
5 | *
Sort an array (in place) by a sorting function
6 | *
Sorts an array in place asynchronously. This function is a yielding
7 | * implementation of Timsort (standard sort used in modern browsers). Timsort
8 | * is fast and stable making it ideal for multi-key sorts. It it not as fast
9 | * as Quicksort.
10 | * @function sortAsync
11 | * @param {Array} array - The array to sort
12 | * @param {SortFunction|ExtractFunction} sort - The method to sort the array
13 | * @returns {Promise.} a promise for the sorted array
14 | * @example
15 | * async function process(data) {
16 | * return await sortAsync(data, v=>v.someProperty)
17 | * }
18 | */
19 | export const sortAsync = wrapAsPromise(sort)
20 |
--------------------------------------------------------------------------------
/src/component/tap.js:
--------------------------------------------------------------------------------
1 | import run from './run'
2 |
3 | /**
4 | * Tap into a pipeline to call a function that will probably
5 | * perform side effects but should not modify the result, its
6 | * return value is ignored
7 | * @param {Function} fn - a function to be called at this point in
8 | * the pipeline
9 | * @returns {AsyncFunction} returning the passed in parameters
10 | */
11 | export function tap(fn) {
12 | return async function (params) {
13 | let result = fn.call(this, params)
14 | if (result) {
15 | if (result.next) {
16 | await run(result)
17 | } else if (result.then) {
18 | await result
19 | }
20 | }
21 | return params
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/component/unique-by-async.js:
--------------------------------------------------------------------------------
1 | import {wrapAsPromiseAndYieldFn} from './async-wrapper-utils'
2 | import {uniqueBy} from './unique-by'
3 |
4 | /**
5 | * Promises the creation of an array with the unique values from the
6 | * input array, the routine is supplied with a
7 | * function that determines on what the array should
8 | * be made unique.
9 | * @param {Array} array
10 | * @param {Map} [fn] - the function to determine uniqueness, if
11 | * omitted then the item itself is used
12 | * @returns {Promise} unique array
13 | */
14 | export const uniqueByAsync = wrapAsPromiseAndYieldFn(uniqueBy)
15 |
--------------------------------------------------------------------------------
/src/component/unique-by.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Create an array with the unique values from the
3 | * input array, the routine is supplied with a
4 | * function that determines on what the array should
5 | * be made unique.
6 | * @param {Array} array
7 | * @param {Map} [fn] - the function to determine uniqueness, if
8 | * omitted then the item itself is used
9 | * @returns {Generator<*, Array, *>}
10 | * @example
11 | *
12 | * const uniqueValues = yield * uniqueBy(records, yielding(r=>r.id))
13 | *
14 | */
15 | export function* uniqueBy(array, fn) {
16 | let set = new Set()
17 | let output = []
18 | let index = 0
19 | for (let item of array) {
20 | if (fn) {
21 | let key = yield* fn(item, index++, array)
22 | if (!set.has(key)) {
23 | output.push(item)
24 | set.add(key)
25 | }
26 | } else {
27 | if (!set.has(item)) {
28 | output.push(item)
29 | set.add(item)
30 | }
31 | }
32 | }
33 | return output
34 | }
35 |
--------------------------------------------------------------------------------
/src/component/update.js:
--------------------------------------------------------------------------------
1 | let requested = false
2 | let animationCallbacks = []
3 |
4 | function nextAnimationFrame(fn) {
5 | if (typeof window === 'undefined') throw new Error('Cannot run without a browser')
6 | if (animationCallbacks.length === 0 && !requested) {
7 | requested = true
8 | requestAnimationFrame(process)
9 | }
10 | animationCallbacks.push(fn)
11 | if (animationCallbacks.length > 10000) animationCallbacks = animationCallbacks.slice(-9000)
12 | }
13 |
14 | function process() {
15 | let callbacks = animationCallbacks
16 | if (callbacks.length) {
17 | requestAnimationFrame(process)
18 | } else {
19 | requested = false
20 | }
21 | animationCallbacks = []
22 | for (let callback of callbacks) {
23 | callback()
24 | }
25 | }
26 |
27 | /**
28 | * Start an animation coroutine, the animation will continue until
29 | * you return and will be broken up between frames by using a
30 | * yield.
31 | *
32 | * @param {AnimationCoroutine|Iterator} coroutine - The animation to run
33 | * @param {...*} [params] - Parameters to be passed to the animation function
34 | * @returns {Promise} a value that will be returned to the caller
35 | * when the animation is complete.
36 | * The promise returned by update has a terminate() method
37 | * that can be used to stop the routine.
38 | */
39 | export function update(coroutine, ...params) {
40 | if (typeof window === 'undefined') throw new Error('Requires a browser to run')
41 | let terminated = false
42 | let resolver = null
43 | const result = new Promise(function (resolve, reject) {
44 | resolver = resolve
45 | const iterator = coroutine.next ? coroutine : coroutine(...params)
46 | nextAnimationFrame(run)
47 |
48 | function run() {
49 | if (terminated) {
50 | iterator.return()
51 | return
52 | }
53 |
54 | try {
55 | const {value, done} = iterator.next()
56 | if (done) {
57 | resolve(value)
58 | return
59 | }
60 | } catch (e) {
61 | reject(e)
62 | return
63 | }
64 |
65 | nextAnimationFrame(run)
66 | }
67 | })
68 | result.terminate = function (result) {
69 | terminated = true
70 | if (resolver) {
71 | resolver(result)
72 | }
73 | }
74 | return result
75 | }
76 |
--------------------------------------------------------------------------------
/src/component/useInternalEngine.js:
--------------------------------------------------------------------------------
1 | import {getCallback, getNodeCallback} from './polyfill'
2 |
3 |
4 | export let request = typeof window === 'undefined' ? getNodeCallback() : window.requestIdleCallback
5 |
6 | /**
7 | * Call with true to use the polyfilled version of
8 | * the idle callback, can be more stable in certain
9 | * circumstances
10 | * @param {Boolean} internal
11 | */
12 | export function useInternalEngine(internal) {
13 | request = internal ? getCallback() : request
14 | }
15 |
--------------------------------------------------------------------------------
/src/component/wrappers.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | import run from './run'
4 | import {call} from './call'
5 |
6 | /**
7 | * Wraps a normal function into a generator function
8 | * that yields on a regular basis
9 | * @param {Function} fn - the function to be wrapped
10 | * @param {number} [frequency=8] -
11 | * the number of times the function should be called
12 | * before performing a yield
13 | * @returns {Coroutine} The wrapped yielding
14 | * version of the function passed
15 | */
16 | export function yielding(fn, frequency = 16) {
17 | let yieldCount = 0;
18 | if(fn._yielding) return fn;
19 | let result = function* (...params) {
20 | let result = fn(...params);
21 | if(result && result.then) {
22 | result = yield result
23 | }
24 | if (yieldCount++ % frequency === 0) {
25 | yield;
26 | }
27 | return result;
28 | };
29 | result._yielding = true
30 | return result
31 | }
32 |
33 | /**
34 | * @callback PromiseFn
35 | * @param {...*} [parameters] the parameters for the function
36 | * @return {Promise} a promise for the result of the function
37 | */
38 |
39 | /**
40 | * Returns a function that will execute the passed
41 | * Coroutine and return a Promise for its result. The
42 | * returned function will take any number of parameters
43 | * and pass them on to the coroutine.
44 | *
45 | * @param {Coroutine} coroutine - The coroutine to run
46 | * @returns {PromiseFn|Function} a function that can be called to execute the coroutine
47 | * and return its result on completion
48 | */
49 | export function wrapAsPromise(coroutine) {
50 | const result = function (...params) {
51 | return run(coroutine(...params))
52 | };
53 | result.with = function (...params) {
54 | return call(result, ...params)
55 | }
56 | return result
57 | }
58 |
59 | export function curryRight(fn, supplied, execute) {
60 | if(fn.length > supplied.length) {
61 | return function(...params) {
62 | return curryRight.call(this, fn, [...params, ...supplied], execute)
63 | }
64 | }
65 | return execute.apply(this, supplied)
66 | }
67 |
--------------------------------------------------------------------------------
/src/component/yastjson/lib/expression.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2020 5u9ar (zhuyingda)
3 | *
4 | * The above copyright notice and this permission notice shall be included in all
5 | * copies or substantial portions of the Software.
6 | *
7 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
13 | * SOFTWARE.
14 | */
15 | export const ExprType = {
16 | Json: "j",
17 | Array: "a",
18 | Object: "o",
19 | Prop: "p",
20 | Value: "v",
21 | };
22 |
--------------------------------------------------------------------------------
/src/component/yastjson/lib/parse.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2020 5u9ar (zhuyingda) (c) 2020 Mike Talbot (Generator mods)
3 | *
4 | * The above copyright notice and this permission notice shall be included in all
5 | * copies or substantial portions of the Software.
6 | *
7 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
13 | * SOFTWARE.
14 | */
15 | import { Tokenizer } from "./tokenizer";
16 | import { AST } from "./ast";
17 | import { ExprType } from "./expression";
18 | import { TokenType } from "./token";
19 | import { yielder } from "./yielder";
20 |
21 | export class ASTParser {
22 | constructor(ast) {
23 | this.ast = ast;
24 | }
25 |
26 | *getJson() {
27 | return yield* this.handleValue(this.ast);
28 | }
29 |
30 | *handleJson(astNode) {
31 | if (astNode.type !== ExprType.Json) {
32 | throw new Error("[parse AST error] unexpected node type, expect Json");
33 | }
34 |
35 | let output;
36 | let node = astNode.childNodeList[0];
37 | if (node.type === ExprType.Array) {
38 | output = [];
39 | for (let item of node.childNodeList) {
40 | output.push(yield* this.handleValue(item.value));
41 | }
42 | } else if (node.type === ExprType.Object) {
43 | output = {};
44 | for (let item of node.childNodeList) {
45 | output[item.propName] = yield* this.handleValue(
46 | item.childNodeList[0].value
47 | );
48 | }
49 | } else {
50 | throw new Error("[parse AST error] unexpected second node type");
51 | }
52 | return output;
53 | }
54 |
55 | *handleValue(astNode) {
56 | if (yielder()) yield;
57 | let token;
58 | switch (astNode.type) {
59 | case TokenType.Null:
60 | return null;
61 | case TokenType.Boolean:
62 | token = astNode.tokens[0].text;
63 | return token === "true";
64 | case TokenType.Number:
65 | let num = +astNode.tokens[0].text;
66 | return num;
67 | case TokenType.String:
68 | return astNode.tokens[0].text.slice(1, -1);
69 | case ExprType.Json:
70 | return yield* this.handleJson(astNode);
71 | default:
72 | throw new Error(
73 | "[parse AST error] unexpected node type, expect a valid Value node"
74 | );
75 | }
76 | }
77 | }
78 |
79 | export function* parse(jsonString) {
80 | const tokenizer = new Tokenizer();
81 | const tokens = yield* tokenizer.tokenize(jsonString);
82 | const astInst = new AST(tokens);
83 | const ast = yield* astInst.buildTree();
84 | const astParser = new ASTParser(ast);
85 | return yield* astParser.getJson();
86 | }
87 |
--------------------------------------------------------------------------------
/src/component/yastjson/lib/token.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2020 5u9ar (zhuyingda)
3 | *
4 | * The above copyright notice and this permission notice shall be included in all
5 | * copies or substantial portions of the Software.
6 | *
7 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
13 | * SOFTWARE.
14 | */
15 | export const TokenType = {
16 | LeftBrace: "{",
17 | RightBrace: "}",
18 | LeftBracket: "l",
19 | RightBracket: "r",
20 | Comma: "c",
21 | Colon: "n",
22 | Null: "0",
23 | Boolean: "t",
24 | Number: "n",
25 | String: "s",
26 | };
27 |
--------------------------------------------------------------------------------
/src/component/yastjson/lib/yielder.js:
--------------------------------------------------------------------------------
1 | let yieldCount = 0;
2 | export function yielder() {
3 | if (yieldCount++ > 100) {
4 | yieldCount = 0;
5 | return true;
6 | }
7 | return false;
8 | }
9 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | overflow: hidden;
9 | height: 100vh;
10 | position: static;
11 | width: 100vw;
12 | }
13 |
14 | code {
15 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
16 | monospace;
17 | }
18 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want your app to work offline and load faster, you can change
15 | // unregister() to register() below. Note this comes with some pitfalls.
16 | // Learn more about service workers: https://bit.ly/CRA-PWA
17 | serviceWorker.unregister();
18 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/src/test/array-async.test.js:
--------------------------------------------------------------------------------
1 | import {reduceAsync} from '../component'
2 | import {should} from 'chai'
3 |
4 | should()
5 |
6 | const INPUT_ARRAY = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
7 |
8 | describe("Array async functions", function () {
9 | it("should handle yielding functions", async function () {
10 | let result = await reduceAsync(INPUT_ARRAY, (a,c)=>a+c)
11 | result.should.equal(210)
12 | })
13 | it("should be able to make a pipeline and execute it", async function () {
14 |
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/src/test/basic-express.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 3000
4 |
5 | const mapAsync = require('../../dist/index').mapAsync
6 |
7 | app.get('/', (req, res) => {
8 | res.send('Hello World!')
9 | })
10 |
11 | app.listen(port, () => {
12 | console.log(`Example app listening at http://localhost:${port}`)
13 | })
14 |
--------------------------------------------------------------------------------
/src/test/compression.test.js:
--------------------------------------------------------------------------------
1 | import {should} from 'chai'
2 | import {compressAsync, decompressAsync, compressToUTF16Async, decompressFromUTF16Async, sortAsync} from '../component'
3 |
4 | should()
5 | const INPUT_ARRAY = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
6 | import test from '../component/yastjson/test/test.json'
7 |
8 | describe('compression', function () {
9 | it('should compress a string', async function () {
10 | let result = await compressAsync('abcde')
11 | let output = await decompressAsync(result)
12 | output.should.eq('abcde')
13 | result.should.eq('ↂテɠꙀ')
14 | })
15 | it('should compress a string to UTF 16', async function () {
16 | let result = await compressToUTF16Async('abcde')
17 | let output = await decompressFromUTF16Async(result)
18 | output.should.eq('abcde')
19 | result.should.eq('ს䁬 ')
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/src/test/functional.test.js:
--------------------------------------------------------------------------------
1 | import {mapAsync, parseAsync, pipe, tap, stringifyAsync, singleton, run, repeat, branch} from '../component'
2 | import {should} from 'chai'
3 | should()
4 |
5 | describe('functional tests', function () {
6 | it('should be able to run a functional pipeline', async function () {
7 | const process = pipe(
8 | parseAsync,
9 | mapAsync.with(v=>v * 2),
10 | stringifyAsync
11 | )
12 | let result = await process('[1,2,3,4]')
13 | result.should.eq('[2,4,6,8]')
14 | })
15 | it('should be able to run a singleton', async function () {
16 | const job = singleton(test1, 99)
17 | let value = 0
18 | job(21).then(r=>value = r)
19 | let result = await job(20)
20 | result.should.eq(20)
21 | value.should.eq(99)
22 |
23 | function * test1(value) {
24 | yield new Promise(resolve=>setTimeout(resolve, 50))
25 | return value
26 | }
27 | })
28 | it('should be able to repeat a function', async function () {
29 | let current
30 | const process = pipe(
31 | parseAsync,
32 | tap(capture),
33 | repeat(double, 2),
34 | stringifyAsync
35 | )
36 | let result = await process('[1,2,3,4]')
37 | result.should.eq('[4,8,12,16]')
38 | current.should.deep.eq([1, 2, 3, 4])
39 | function double(values) {
40 | return values.map(v=>v*2)
41 | }
42 | function capture(v) {
43 | current = v
44 | }
45 | })
46 | it('should be able to branch', async function () {
47 | let output
48 | const process = pipe(
49 | parseAsync,
50 | branch(pipe(stringifyAsync, tap(capture))),
51 | mapAsync.with(v => v * 2),
52 | stringifyAsync
53 | )
54 | let result = await process('[1,2,3,4]')
55 | result.should.eq('[2,4,6,8]')
56 | output.should.eq('[1,2,3,4]')
57 | function capture(values) {
58 | output = values
59 | }
60 | })
61 | })
62 |
--------------------------------------------------------------------------------
/src/test/json.test.js:
--------------------------------------------------------------------------------
1 | import {parseAsync, stringifyAsync} from '../component'
2 | import test from '../component/yastjson/test/test.json'
3 | const testJSON = JSON.stringify(test)
4 | import {should} from 'chai'
5 |
6 | should()
7 |
8 | describe('JSON tests', function () {
9 | it("should stringify JSON", async function () {
10 | let json = await stringifyAsync({a: 1, c: 2, d: 3})
11 | json.should.eq('{"a":1,"c":2,"d":3}')
12 | })
13 | it("should stringify empty strings", async function () {
14 | let data = {name: "person", extra_info: '{country:"",age:35}'}
15 | let json = await stringifyAsync(data)
16 | json.should.eq(JSON.stringify(data))
17 | console.log(JSON.stringify(data))
18 | })
19 | it("should parse JSON", async function () {
20 | let item = await parseAsync('{"a":1,"c":2,"d":3,"e":{"a":1}}')
21 | item.a.should.eq(1)
22 | item.d.should.eq(3)
23 | item.e.a.should.eq(1)
24 | })
25 | it("should parse whitespaced JSON", async function () {
26 | let item = await parseAsync(' { "a":1, "c":2, "d":3, "e": { "a": 1} }')
27 | item.a.should.eq(1)
28 | item.d.should.eq(3)
29 | item.e.a.should.eq(1)
30 | })
31 | it("should parse realistic json", async function () {
32 | let item = await parseAsync(testJSON)
33 | item[0].friends.length.should.eq(3)
34 | })
35 | it("should be able to stringify complex JSON", async function () {
36 | let result = await stringifyAsync(test)
37 | result.should.eq(testJSON)
38 | })
39 |
40 | })
41 |
--------------------------------------------------------------------------------
/src/test/sort.test.js:
--------------------------------------------------------------------------------
1 | import {should} from 'chai'
2 | import {sortAsync} from '../component'
3 |
4 | should()
5 | const INPUT_ARRAY = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
6 | import test from '../component/yastjson/test/test.json'
7 |
8 | const SORT_ARRAY = ['z', '1', 'a', 'a', 'a', 'a', '2','2', 'b', 'f', 'f', 'c', 'c']
9 |
10 | describe('sorting', function () {
11 | it('should be able to sort an array', async function () {
12 | const result = await sortAsync([...INPUT_ARRAY], v=>-v)
13 | result[0].should.eq(20)
14 | result[19].should.eq(1)
15 | })
16 | it('should be able to sort more complicated things!', async function () {
17 | const result = await sortAsync([...test], v=>v.age)
18 | result[0].name.first.should.eq('Leticia')
19 | })
20 | it('should sort an alpha array', async function () {
21 | const result = await sortAsync([...SORT_ARRAY])
22 | result[0].should.eq('1')
23 | result[12].should.eq('z')
24 | })
25 | it('should sort a numeric array', async function () {
26 | const result = await sortAsync([...INPUT_ARRAY])
27 | result[0].should.eq(1)
28 | result[12].should.eq(13)
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/template/LICENSE:
--------------------------------------------------------------------------------
1 | ## JSDoc 3
2 |
3 | JSDoc 3 is free software, licensed under the Apache License, Version 2.0 (the
4 | "License"). Commercial and non-commercial use are permitted in compliance with
5 | the License.
6 |
7 | Copyright (c) 2011-2015 Michael Mathews and the
8 | [contributors to JSDoc](https://github.com/jsdoc3/jsdoc/graphs/contributors).
9 | All rights reserved.
10 |
11 | You may obtain a copy of the License at:
12 | http://www.apache.org/licenses/LICENSE-2.0
13 |
14 | In addition, a copy of the License is included with this distribution.
15 |
16 | As stated in Section 7, "Disclaimer of Warranty," of the License:
17 |
18 | > Licensor provides the Work (and each Contributor provides its Contributions)
19 | > on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
20 | > express or implied, including, without limitation, any warranties or
21 | > conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
22 | > PARTICULAR PURPOSE. You are solely responsible for determining the
23 | > appropriateness of using or redistributing the Work and assume any risks
24 | > associated with Your exercise of permissions under this License.
25 |
26 | The source code for JSDoc 3 is available at:
27 | https://github.com/jsdoc3/jsdoc
28 |
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Bold-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Bold-webfont.eot
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Bold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Bold-webfont.woff
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-BoldItalic-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-BoldItalic-webfont.eot
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-BoldItalic-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-BoldItalic-webfont.woff
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Italic-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Italic-webfont.eot
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Italic-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Italic-webfont.woff
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Light-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Light-webfont.eot
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Light-webfont.woff
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-LightItalic-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-LightItalic-webfont.eot
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-LightItalic-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-LightItalic-webfont.woff
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Regular-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Regular-webfont.eot
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Regular-webfont.woff
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Semibold-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Semibold-webfont.eot
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Semibold-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Semibold-webfont.ttf
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-Semibold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-Semibold-webfont.woff
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-SemiboldItalic-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-SemiboldItalic-webfont.eot
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-SemiboldItalic-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-SemiboldItalic-webfont.ttf
--------------------------------------------------------------------------------
/template/static/fonts/OpenSans-SemiboldItalic-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketalbot/js-coroutines/e749517ee4cc5b191947e4e8b01837990afe20a8/template/static/fonts/OpenSans-SemiboldItalic-webfont.woff
--------------------------------------------------------------------------------
/template/static/icons/home.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/template/static/icons/search.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/template/static/scripts/linenumber.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /* global document */
4 | (function () {
5 | var lineId, lines, totalLines, anchorHash;
6 | var source = document.getElementsByClassName('prettyprint source linenums');
7 | var i = 0;
8 | var lineNumber = 0;
9 |
10 | if (source && source[0]) {
11 | anchorHash = document.location.hash.substring(1);
12 | lines = source[0].getElementsByTagName('li');
13 | totalLines = lines.length;
14 |
15 | for (; i < totalLines; i++) {
16 | lineNumber++;
17 | lineId = 'line' + lineNumber;
18 | lines[i].id = lineId;
19 | if (lineId === anchorHash) {
20 | lines[i].className += ' selected';
21 | }
22 | }
23 | }
24 | })();
25 |
--------------------------------------------------------------------------------
/template/static/scripts/pagelocation.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(document).ready(function () {
4 | var currentSectionNav, target;
5 |
6 | // If an anchor hash is in the URL highlight the menu item
7 | highlightActiveHash();
8 | // If a specific page section is in the URL highlight the menu item
9 | highlightActiveSection();
10 |
11 | // If a specific page section is in the URL scroll that section up to the top
12 | currentSectionNav = $('#' + getCurrentSectionName() + '-nav');
13 |
14 | if (currentSectionNav.position()) {
15 | $('nav').scrollTop(currentSectionNav.position().top);
16 | }
17 |
18 | // function to scroll to anchor when clicking an anchor linl
19 | $('a[href*="#"]:not([href="#"])').click(function () {
20 | /* eslint-disable no-invalid-this */
21 | if (location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '') && location.hostname === this.hostname) {
22 | target = $(this.hash);
23 | target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
24 | if (target.length) {
25 | $('html, body').animate({
26 | scrollTop: target.offset().top
27 | }, 1000);
28 | }
29 | }
30 | /* eslint-enable no-invalid-this */
31 | });
32 | });
33 |
34 | // If a new anchor section is selected, change the hightlighted menu item
35 | $(window).bind('hashchange', function (event) {
36 | highlightActiveHash(event);
37 | });
38 |
39 | function highlightActiveHash(event) {
40 | var oldUrl, oldSubSectionElement;
41 |
42 | // check for and remove old hash active state
43 | if (event && event.originalEvent.oldURL) {
44 | oldUrl = event.originalEvent.oldURL;
45 |
46 | if (oldUrl.indexOf('#') > -1) {
47 | oldSubSectionElement = $('#' + getCurrentSectionName() + '-' + oldUrl.substring(oldUrl.indexOf('#') + 1) + '-nav');
48 |
49 | if (oldSubSectionElement) {
50 | oldSubSectionElement.removeClass('active');
51 | }
52 | }
53 | }
54 |
55 | if (getCurrentHashName()) {
56 | $('#' + getCurrentSectionName() + '-' + getCurrentHashName() + '-nav').addClass('active');
57 | }
58 | }
59 |
60 | function highlightActiveSection() {
61 | var pageId = getCurrentSectionName();
62 |
63 | $('#' + pageId + '-nav').addClass('active');
64 | }
65 |
66 | function getCurrentSectionName() {
67 | var path = window.location.pathname;
68 | var pageUrl = path.split('/').pop();
69 |
70 | var sectionName = pageUrl.substring(0, pageUrl.indexOf('.'));
71 |
72 | // remove the wodr module- if its in the url
73 | sectionName = sectionName.replace('module-', '');
74 |
75 | return sectionName;
76 | }
77 |
78 | function getCurrentHashName() {
79 | var pageSubSectionId;
80 | var pageSubSectionHash = window.location.hash;
81 |
82 | if (pageSubSectionHash) {
83 | pageSubSectionId = pageSubSectionHash.substring(1).replace('.', '');
84 |
85 | return pageSubSectionId;
86 | }
87 |
88 | return false;
89 | }
90 |
--------------------------------------------------------------------------------
/template/static/styles/collapse.css:
--------------------------------------------------------------------------------
1 | @media only screen and (min-width: 681px) {
2 | nav > ul > li:hover .methods,
3 | .active .methods {
4 | display: block;
5 | }
6 |
7 | .methods {
8 | display: none;
9 | }
10 |
11 | nav > ul > li {
12 | padding: 20px 0;
13 | }
14 |
15 | nav > ul > li > a {
16 | padding: 0;
17 | }
18 |
19 | nav > ul > li.active a {
20 | margin-bottom: 10px;
21 | }
22 |
23 | nav > ul > li:hover > a,
24 | nav > ul > li.active > a {
25 | margin-bottom: 15px;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/template/static/styles/prettify-jsdoc.css:
--------------------------------------------------------------------------------
1 | /* JSDoc prettify.js theme */
2 |
3 | /* plain text */
4 | .pln {
5 | color: #000000;
6 | font-weight: normal;
7 | font-style: normal;
8 | }
9 |
10 | /* string content */
11 | .str {
12 | color: hsl(104, 100%, 24%);
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
17 | /* a keyword */
18 | .kwd {
19 | color: #000000;
20 | font-weight: bold;
21 | font-style: normal;
22 | }
23 |
24 | /* a comment */
25 | .com {
26 | font-weight: normal;
27 | font-style: italic;
28 | }
29 |
30 | /* a type name */
31 | .typ {
32 | color: #000000;
33 | font-weight: normal;
34 | font-style: normal;
35 | }
36 |
37 | /* a literal value */
38 | .lit {
39 | color: #006400;
40 | font-weight: normal;
41 | font-style: normal;
42 | }
43 |
44 | /* punctuation */
45 | .pun {
46 | color: #000000;
47 | font-weight: bold;
48 | font-style: normal;
49 | }
50 |
51 | /* lisp open bracket */
52 | .opn {
53 | color: #000000;
54 | font-weight: bold;
55 | font-style: normal;
56 | }
57 |
58 | /* lisp close bracket */
59 | .clo {
60 | color: #000000;
61 | font-weight: bold;
62 | font-style: normal;
63 | }
64 |
65 | /* a markup tag name */
66 | .tag {
67 | color: #006400;
68 | font-weight: normal;
69 | font-style: normal;
70 | }
71 |
72 | /* a markup attribute name */
73 | .atn {
74 | color: #006400;
75 | font-weight: normal;
76 | font-style: normal;
77 | }
78 |
79 | /* a markup attribute value */
80 | .atv {
81 | color: #006400;
82 | font-weight: normal;
83 | font-style: normal;
84 | }
85 |
86 | /* a declaration */
87 | .dec {
88 | color: #000000;
89 | font-weight: bold;
90 | font-style: normal;
91 | }
92 |
93 | /* a variable name */
94 | .var {
95 | color: #000000;
96 | font-weight: normal;
97 | font-style: normal;
98 | }
99 |
100 | /* a function name */
101 | .fun {
102 | color: #000000;
103 | font-weight: bold;
104 | font-style: normal;
105 | }
106 |
107 | /* Specify class=linenums on a pre to get line numbering */
108 | ol.linenums {
109 | margin-top: 0;
110 | margin-bottom: 0;
111 | }
112 |
--------------------------------------------------------------------------------
/template/static/styles/prettify-tomorrow.css:
--------------------------------------------------------------------------------
1 | /* Tomorrow Theme */
2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */
3 | /* Pretty printing styles. Used with prettify.js. */
4 | /* SPAN elements with the classes below are added by prettyprint. */
5 | /* plain text */
6 | .pln {
7 | color: #4d4d4c; }
8 |
9 | @media screen {
10 | /* string content */
11 | .str {
12 | color: hsl(104, 100%, 24%); }
13 |
14 | /* a keyword */
15 | .kwd {
16 | color: hsl(240, 100%, 50%); }
17 |
18 | /* a comment */
19 | .com {
20 | color: hsl(0, 0%, 60%); }
21 |
22 | /* a type name */
23 | .typ {
24 | color: hsl(240, 100%, 32%); }
25 |
26 | /* a literal value */
27 | .lit {
28 | color: hsl(240, 100%, 40%); }
29 |
30 | /* punctuation */
31 | .pun {
32 | color: #000000; }
33 |
34 | /* lisp open bracket */
35 | .opn {
36 | color: #000000; }
37 |
38 | /* lisp close bracket */
39 | .clo {
40 | color: #000000; }
41 |
42 | /* a markup tag name */
43 | .tag {
44 | color: #c82829; }
45 |
46 | /* a markup attribute name */
47 | .atn {
48 | color: #f5871f; }
49 |
50 | /* a markup attribute value */
51 | .atv {
52 | color: #3e999f; }
53 |
54 | /* a declaration */
55 | .dec {
56 | color: #f5871f; }
57 |
58 | /* a variable name */
59 | .var {
60 | color: #c82829; }
61 |
62 | /* a function name */
63 | .fun {
64 | color: #4271ae; } }
65 | /* Use higher contrast and text-weight for printable form. */
66 | @media print, projection {
67 | .str {
68 | color: #060; }
69 |
70 | .kwd {
71 | color: #006;
72 | font-weight: bold; }
73 |
74 | .com {
75 | color: #600;
76 | font-style: italic; }
77 |
78 | .typ {
79 | color: #404;
80 | font-weight: bold; }
81 |
82 | .lit {
83 | color: #044; }
84 |
85 | .pun, .opn, .clo {
86 | color: #440; }
87 |
88 | .tag {
89 | color: #006;
90 | font-weight: bold; }
91 |
92 | .atn {
93 | color: #404; }
94 |
95 | .atv {
96 | color: #060; } }
97 | /* Style */
98 | /*
99 | pre.prettyprint {
100 | background: white;
101 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
102 | font-size: 12px;
103 | line-height: 1.5;
104 | border: 1px solid #ccc;
105 | padding: 10px; }
106 | */
107 |
108 | /* Get LI elements to show when they are in the main article */
109 | article ul li {
110 | list-style-type: circle;
111 | margin-left: 25px;
112 | }
113 |
114 | /* Specify class=linenums on a pre to get line numbering */
115 | ol.linenums {
116 | margin-top: 0;
117 | margin-bottom: 0; }
118 |
119 | /* IE indents via margin-left */
120 | li.L0,
121 | li.L1,
122 | li.L2,
123 | li.L3,
124 | li.L4,
125 | li.L5,
126 | li.L6,
127 | li.L7,
128 | li.L8,
129 | li.L9 {
130 | /* */ }
131 |
132 | /* Alternate shading for lines */
133 | li.L1,
134 | li.L3,
135 | li.L5,
136 | li.L7,
137 | li.L9 {
138 | /* */ }
139 |
--------------------------------------------------------------------------------
/template/tmpl/augments-spread.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |