Initial commit: MVP+ wish board with FastAPI + Tailwind
This commit is contained in:
commit
cd945a6128
2277 files changed
+843095
No files matched your search
+4
@@ -0,0 +1,4 @@
|
||||
# Changelog
|
||||
|
||||
This project adheres to [Semantic Versioning 2.0](http://semver.org/).
|
||||
All release notes and upgrade notes can be found on our [Github Releases](https://github.com/alexreardon/raf-schd/releases) page.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Alex Reardon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
# raf-schd
|
||||
|
||||
A `throttle` function that uses [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) to limit the rate at which a function is called.
|
||||
|
||||
[](https://travis-ci.org/alexreardon/raf-schd) [](https://david-dm.org/alexreardon/raf-schd) [](https://www.npmjs.com/package/raf-schd) [](http://semver.org/spec/v2.0.0.html)
|
||||
|
||||
> For background information on rate limiting functions, see [Rate limiting functions from scratch](https://www.youtube.com/watch?v=g_3e_bNU2e0)
|
||||
|
||||
```js
|
||||
import rafSchd from 'raf-schd';
|
||||
|
||||
const expensiveFn = arg => {
|
||||
//...
|
||||
console.log(arg);
|
||||
};
|
||||
|
||||
const schedule = rafSchd(expensiveFn);
|
||||
|
||||
schedule('foo');
|
||||
schedule('bar');
|
||||
schedule('baz');
|
||||
|
||||
// animation frame fires
|
||||
|
||||
// => 'baz'
|
||||
```
|
||||
|
||||
## Why?
|
||||
|
||||
`raf-schd` supports the use case where you want to limit the rate at which your functions are called based on `requestAnimationFrame`. Unlike a standard `throttle` function, `raf-schd` uses `requestAnimationFrame` to rate limit, rather than waiting a fixed amount of time. Using `requestAnimationFrame` for throttling is powerful because the browser will automatically reduce the amount of frames provided based on the available resources. So if the browser only provides 30fps then your throttled function will only be called 30 times.
|
||||
|
||||
`raf-schd` is an **extremely** useful performance utility.
|
||||
|
||||
### Without `raf-schd`
|
||||
|
||||
> Optimised scroll listener example taken from [MDN](https://developer.mozilla.org/en-US/docs/Web/Events/scroll)
|
||||
|
||||
```js
|
||||
var last_known_scroll_position = 0;
|
||||
var ticking = false;
|
||||
|
||||
function doSomething(scroll_pos) {
|
||||
// do something with the scroll position
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', function(e) {
|
||||
last_known_scroll_position = window.scrollY;
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(function() {
|
||||
doSomething(last_known_scroll_position);
|
||||
ticking = false;
|
||||
});
|
||||
}
|
||||
ticking = true;
|
||||
});
|
||||
```
|
||||
|
||||
### With `raf-schd`
|
||||
|
||||
```js
|
||||
import rafSchd from 'raf-schd';
|
||||
|
||||
function doSomething(scroll_pos) {
|
||||
// do something with the scroll position
|
||||
}
|
||||
|
||||
const schedule = rafSchd(doSomething);
|
||||
|
||||
window.addEventListener('scroll', function() {
|
||||
schedule(window.scrollY);
|
||||
});
|
||||
```
|
||||
|
||||
At the top level `raf-schd` accepts any function a returns a new `ResultFn` (a function that wraps your original function).
|
||||
|
||||
The `ResultFn` will execute your function with the **latest arguments** provided to it on the next animation frame.
|
||||
|
||||
### Throttled with latest argument
|
||||
|
||||
```js
|
||||
import rafSchd from 'raf-schd';
|
||||
|
||||
const doSomething = () => {...};
|
||||
|
||||
const schedule = rafSchd(doSomething);
|
||||
|
||||
schedule(1, 2);
|
||||
schedule(3, 4);
|
||||
schedule(5, 6);
|
||||
|
||||
// animation frame fires
|
||||
|
||||
// do something called with => '5, 6'
|
||||
```
|
||||
|
||||
### Cancelling a frame with `.cancel`
|
||||
|
||||
`raf-schd` adds a `.cancel` property to the `ResultFn` so that it can be easily cancelled. The frame will only be cancelled if it has not yet executed.
|
||||
|
||||
```js
|
||||
const schedule = rafSchd(doSomething);
|
||||
|
||||
schedule('foo');
|
||||
|
||||
schedule.cancel();
|
||||
|
||||
// now doSomething will not be executed in the next animation frame
|
||||
```
|
||||
|
||||
## Types
|
||||
|
||||
### `rafSchedule`
|
||||
|
||||
```js
|
||||
type rafSchedule = (fn: Function) => ResultFn;
|
||||
|
||||
// Adding a .cancel property to the WrapperFn
|
||||
|
||||
type WrapperFn = (...arg: mixed[]) => void;
|
||||
type CancelFn = {|
|
||||
cancel: () => void,
|
||||
|};
|
||||
type ResultFn = WrapperFn & CancelFn;
|
||||
```
|
||||
|
||||
## Testing your code
|
||||
|
||||
If you want to really ensure that your code is working how you intend it to - use [`raf-stub`](https://github.com/alexreardon/raf-stub) to test your animation frame logic.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# yarn
|
||||
yarn add raf-schd
|
||||
|
||||
# npm
|
||||
npm install raf-schd --save
|
||||
```
|
||||
|
||||
## Module usage
|
||||
|
||||
### ES6 module
|
||||
|
||||
```js
|
||||
import rafSchd from 'raf-schd';
|
||||
```
|
||||
|
||||
### CommonJS
|
||||
|
||||
If you are in a CommonJS environment (eg [Node](https://nodejs.org)), then **you will need add `.default` to your import**:
|
||||
|
||||
```js
|
||||
const rafSchd = require('raf-schd').default;
|
||||
```
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "raf-schd",
|
||||
"version": "4.0.3",
|
||||
"description": "A scheduler based on requestAnimationFrame",
|
||||
"main": "dist/raf-schd.cjs.js",
|
||||
"module": "dist/raf-schd.esm.js",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"/dist",
|
||||
"/src"
|
||||
],
|
||||
"author": "Alex Reardon <alexreardon@gmail.com>",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/alexreardon/raf-schd.git"
|
||||
},
|
||||
"keywords": [
|
||||
"performance",
|
||||
"raf",
|
||||
"requestAnimationFrame",
|
||||
"cancelAnimationFrame"
|
||||
],
|
||||
"config": {
|
||||
"prettier_target": "*.{js,md,json} src/**/*.{js,md,json} test/**/*.{js,md,json}"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn run build:clean && yarn run build:dist && yarn run build:flow",
|
||||
"test": "jest",
|
||||
"validate": "yarn run prettier:check && yarn run typecheck",
|
||||
"prettier:check": "prettier --debug-check $npm_package_config_prettier_target",
|
||||
"prettier:write": "prettier --write $npm_package_config_prettier_target",
|
||||
"typecheck": "flow check",
|
||||
"build:clean": "rimraf dist",
|
||||
"build:dist": "rollup -c",
|
||||
"build:flow": "echo \"// @flow\n\nexport * from '../src';\" > dist/raf-schd.cjs.js.flow",
|
||||
"prepublish": "yarn run build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.5.0",
|
||||
"@babel/preset-env": "^7.5.2",
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"babel-eslint": "10.0.2",
|
||||
"babel-jest": "^24.8.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"flow-bin": "0.102.0",
|
||||
"jest": "24.8.0",
|
||||
"prettier": "^1.18.2",
|
||||
"raf-stub": "3.0.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"rollup": "^1.16.6",
|
||||
"rollup-plugin-babel": "^4.3.3",
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"rollup-plugin-terser": "^5.1.1"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
// @flow
|
||||
|
||||
type WrapperFn<T> = {
|
||||
[[call]]: (...T) => void,
|
||||
cancel: () => void,
|
||||
};
|
||||
|
||||
const rafSchd = <T: $ReadOnlyArray<any>>(
|
||||
fn: (...T) => void,
|
||||
): WrapperFn<T> => {
|
||||
let lastArgs: T = ([]: any);
|
||||
let frameId: ?AnimationFrameID = null;
|
||||
|
||||
const wrapperFn: WrapperFn<T> = (...args: T) => {
|
||||
// Always capture the latest value
|
||||
lastArgs = args;
|
||||
|
||||
// There is already a frame queued
|
||||
if (frameId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Schedule a new frame
|
||||
frameId = requestAnimationFrame(() => {
|
||||
frameId = null;
|
||||
fn(...lastArgs);
|
||||
});
|
||||
};
|
||||
|
||||
// Adding cancel property to result function
|
||||
wrapperFn.cancel = () => {
|
||||
if (!frameId) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancelAnimationFrame(frameId);
|
||||
frameId = null;
|
||||
};
|
||||
|
||||
return wrapperFn;
|
||||
};
|
||||
|
||||
export default rafSchd;
|
||||
Reference in new issue
Block a user