mirror: A tiny/fast dataloader implementation
0

Configure Feed

Select the types of activity you want to include in your feed.

feat: init

Marais Rossouw (Mar 13, 2023, 3:02 PM +1000) dae5dcb8

+1021
+9
.editorconfig
··· 1 + root = true 2 + 3 + [*] 4 + charset = utf-8 5 + end_of_line = lf 6 + indent_style = tab 7 + indent_size = 4 8 + insert_final_newline = true 9 + trim_trailing_whitespace = true
+40
.github/workflows/ci.yml
··· 1 + name: CI 2 + 3 + on: 4 + push: 5 + branches: [main] 6 + pull_request: {} 7 + 8 + jobs: 9 + test: 10 + name: Node.js v${{ matrix.node }} 11 + runs-on: ubuntu-latest 12 + strategy: 13 + matrix: 14 + node: [14, 16, 18] 15 + steps: 16 + - uses: actions/checkout@main 17 + 18 + - name: (env) setup pnpm 19 + uses: pnpm/action-setup@v2.0.1 20 + with: 21 + version: 7.28.0 22 + 23 + - name: (env) setup node v${{ matrix.node }} 24 + uses: actions/setup-node@main 25 + with: 26 + node-version: ${{ matrix.node }} 27 + cache: pnpm 28 + check-latest: true 29 + 30 + - name: Install 31 + run: pnpm install 32 + 33 + - name: Compiles 34 + run: pnpm build 35 + 36 + - name: Test 37 + run: pnpm test 38 + 39 + - name: Check Types 40 + run: pnpm typecheck
+16
.gitignore
··· 1 + node_modules 2 + .DS_Store 3 + *-lock.json 4 + *.lock 5 + *.log 6 + 7 + /coverage 8 + /.nyc_output 9 + 10 + # Editors 11 + *.iml 12 + /.idea 13 + /.vscode 14 + 15 + # Code 16 + /index.*
+2
.prettierignore
··· 1 + *-lock.yaml 2 + /index.*
+21
license
··· 1 + MIT License 2 + 3 + Copyright (c) Marais Rossouw <me@marais.dev> 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining a copy 6 + of this software and associated documentation files (the "Software"), to deal 7 + in the Software without restriction, including without limitation the rights 8 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 + copies of the Software, and to permit persons to whom the Software is 10 + furnished to do so, subject to the following conditions: 11 + 12 + The above copyright notice and this permission notice shall be included in all 13 + copies or substantial portions of the Software. 14 + 15 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + SOFTWARE.
+48
package.json
··· 1 + { 2 + "name": "dldr", 3 + "version": "0.0.2", 4 + "description": "A fast 365B dataloader implementation", 5 + "keywords": [ 6 + "dataloader", 7 + "batch", 8 + "graphql", 9 + "utility" 10 + ], 11 + "repository": "maraisr/dldr", 12 + "license": "MIT", 13 + "author": "Marais Rossow <me@marais.dev> (https://marais.io)", 14 + "sideEffects": false, 15 + "exports": { 16 + ".": { 17 + "types": "./index.d.ts", 18 + "import": "./index.mjs", 19 + "require": "./index.js" 20 + }, 21 + "./package.json": "./package.json" 22 + }, 23 + "main": "index.js", 24 + "module": "index.mjs", 25 + "types": "index.d.ts", 26 + "files": [ 27 + "*.d.ts", 28 + "index.js", 29 + "index.mjs" 30 + ], 31 + "scripts": { 32 + "build": "bundt --minify", 33 + "format": "prettier --write .", 34 + "test": "uvu src \".spec.ts$\" -r tsm", 35 + "typecheck": "tsc --noEmit" 36 + }, 37 + "prettier": "@marais/prettier", 38 + "devDependencies": { 39 + "@marais/prettier": "0.0.1", 40 + "@marais/tsconfig": "0.0.3", 41 + "bundt": "2.0.0-next.5", 42 + "nanospy": "0.5.0", 43 + "prettier": "2.8.4", 44 + "tsm": "2.3.0", 45 + "typescript": "4.9.5", 46 + "uvu": "0.5.6" 47 + } 48 + }
+629
pnpm-lock.yaml
··· 1 + lockfileVersion: 5.4 2 + 3 + specifiers: 4 + '@marais/prettier': 0.0.1 5 + '@marais/tsconfig': 0.0.3 6 + bundt: 2.0.0-next.5 7 + nanospy: 0.5.0 8 + prettier: 2.8.4 9 + tsm: 2.3.0 10 + typescript: 4.9.5 11 + uvu: 0.5.6 12 + 13 + devDependencies: 14 + '@marais/prettier': 0.0.1 15 + '@marais/tsconfig': 0.0.3 16 + bundt: 2.0.0-next.5 17 + nanospy: 0.5.0 18 + prettier: 2.8.4 19 + tsm: 2.3.0 20 + typescript: 4.9.5 21 + uvu: 0.5.6 22 + 23 + packages: 24 + 25 + /@esbuild/android-arm/0.15.18: 26 + resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} 27 + engines: {node: '>=12'} 28 + cpu: [arm] 29 + os: [android] 30 + requiresBuild: true 31 + dev: true 32 + optional: true 33 + 34 + /@esbuild/linux-loong64/0.14.54: 35 + resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} 36 + engines: {node: '>=12'} 37 + cpu: [loong64] 38 + os: [linux] 39 + requiresBuild: true 40 + dev: true 41 + optional: true 42 + 43 + /@esbuild/linux-loong64/0.15.18: 44 + resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} 45 + engines: {node: '>=12'} 46 + cpu: [loong64] 47 + os: [linux] 48 + requiresBuild: true 49 + dev: true 50 + optional: true 51 + 52 + /@jridgewell/gen-mapping/0.3.2: 53 + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} 54 + engines: {node: '>=6.0.0'} 55 + dependencies: 56 + '@jridgewell/set-array': 1.1.2 57 + '@jridgewell/sourcemap-codec': 1.4.14 58 + '@jridgewell/trace-mapping': 0.3.17 59 + dev: true 60 + 61 + /@jridgewell/resolve-uri/3.1.0: 62 + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} 63 + engines: {node: '>=6.0.0'} 64 + dev: true 65 + 66 + /@jridgewell/set-array/1.1.2: 67 + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} 68 + engines: {node: '>=6.0.0'} 69 + dev: true 70 + 71 + /@jridgewell/source-map/0.3.2: 72 + resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} 73 + dependencies: 74 + '@jridgewell/gen-mapping': 0.3.2 75 + '@jridgewell/trace-mapping': 0.3.17 76 + dev: true 77 + 78 + /@jridgewell/sourcemap-codec/1.4.14: 79 + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} 80 + dev: true 81 + 82 + /@jridgewell/trace-mapping/0.3.17: 83 + resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} 84 + dependencies: 85 + '@jridgewell/resolve-uri': 3.1.0 86 + '@jridgewell/sourcemap-codec': 1.4.14 87 + dev: true 88 + 89 + /@marais/prettier/0.0.1: 90 + resolution: {integrity: sha512-2dSx4GqwgEylxvSamA5jH1XTXx9QrM89CToB1xiciJbtYv6PMWvX0lZ2viWDk2viWh91/Qd4cpBAvdi+LDKC0A==} 91 + dev: true 92 + 93 + /@marais/tsconfig/0.0.3: 94 + resolution: {integrity: sha512-KRJiOww98fD1ODCGxTiA8EIiXDtm7VaIEVfkeQ8yHA4SUcuBib85qgM1bQ6wD8H72YR8MMmXAxTfBusLBPnqjw==} 95 + dev: true 96 + 97 + /acorn/8.8.2: 98 + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} 99 + engines: {node: '>=0.4.0'} 100 + hasBin: true 101 + dev: true 102 + 103 + /buffer-from/1.1.2: 104 + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 105 + dev: true 106 + 107 + /bundt/2.0.0-next.5: 108 + resolution: {integrity: sha512-uoMMvvZUGRVyVbd0tls6ZU3bASc0lZt3b0iD3AE2J9sKgnsKJoWAWe4uUcCkla+Dx+T006ZERBvq0PY3iNuXlw==} 109 + engines: {node: '>=12'} 110 + hasBin: true 111 + dependencies: 112 + esbuild: 0.14.54 113 + rewrite-imports: 2.0.3 114 + terser: 5.16.6 115 + dev: true 116 + 117 + /commander/2.20.3: 118 + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} 119 + dev: true 120 + 121 + /dequal/2.0.3: 122 + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} 123 + engines: {node: '>=6'} 124 + dev: true 125 + 126 + /diff/5.1.0: 127 + resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} 128 + engines: {node: '>=0.3.1'} 129 + dev: true 130 + 131 + /esbuild-android-64/0.14.54: 132 + resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} 133 + engines: {node: '>=12'} 134 + cpu: [x64] 135 + os: [android] 136 + requiresBuild: true 137 + dev: true 138 + optional: true 139 + 140 + /esbuild-android-64/0.15.18: 141 + resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} 142 + engines: {node: '>=12'} 143 + cpu: [x64] 144 + os: [android] 145 + requiresBuild: true 146 + dev: true 147 + optional: true 148 + 149 + /esbuild-android-arm64/0.14.54: 150 + resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} 151 + engines: {node: '>=12'} 152 + cpu: [arm64] 153 + os: [android] 154 + requiresBuild: true 155 + dev: true 156 + optional: true 157 + 158 + /esbuild-android-arm64/0.15.18: 159 + resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==} 160 + engines: {node: '>=12'} 161 + cpu: [arm64] 162 + os: [android] 163 + requiresBuild: true 164 + dev: true 165 + optional: true 166 + 167 + /esbuild-darwin-64/0.14.54: 168 + resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} 169 + engines: {node: '>=12'} 170 + cpu: [x64] 171 + os: [darwin] 172 + requiresBuild: true 173 + dev: true 174 + optional: true 175 + 176 + /esbuild-darwin-64/0.15.18: 177 + resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==} 178 + engines: {node: '>=12'} 179 + cpu: [x64] 180 + os: [darwin] 181 + requiresBuild: true 182 + dev: true 183 + optional: true 184 + 185 + /esbuild-darwin-arm64/0.14.54: 186 + resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} 187 + engines: {node: '>=12'} 188 + cpu: [arm64] 189 + os: [darwin] 190 + requiresBuild: true 191 + dev: true 192 + optional: true 193 + 194 + /esbuild-darwin-arm64/0.15.18: 195 + resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==} 196 + engines: {node: '>=12'} 197 + cpu: [arm64] 198 + os: [darwin] 199 + requiresBuild: true 200 + dev: true 201 + optional: true 202 + 203 + /esbuild-freebsd-64/0.14.54: 204 + resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} 205 + engines: {node: '>=12'} 206 + cpu: [x64] 207 + os: [freebsd] 208 + requiresBuild: true 209 + dev: true 210 + optional: true 211 + 212 + /esbuild-freebsd-64/0.15.18: 213 + resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==} 214 + engines: {node: '>=12'} 215 + cpu: [x64] 216 + os: [freebsd] 217 + requiresBuild: true 218 + dev: true 219 + optional: true 220 + 221 + /esbuild-freebsd-arm64/0.14.54: 222 + resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} 223 + engines: {node: '>=12'} 224 + cpu: [arm64] 225 + os: [freebsd] 226 + requiresBuild: true 227 + dev: true 228 + optional: true 229 + 230 + /esbuild-freebsd-arm64/0.15.18: 231 + resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==} 232 + engines: {node: '>=12'} 233 + cpu: [arm64] 234 + os: [freebsd] 235 + requiresBuild: true 236 + dev: true 237 + optional: true 238 + 239 + /esbuild-linux-32/0.14.54: 240 + resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} 241 + engines: {node: '>=12'} 242 + cpu: [ia32] 243 + os: [linux] 244 + requiresBuild: true 245 + dev: true 246 + optional: true 247 + 248 + /esbuild-linux-32/0.15.18: 249 + resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==} 250 + engines: {node: '>=12'} 251 + cpu: [ia32] 252 + os: [linux] 253 + requiresBuild: true 254 + dev: true 255 + optional: true 256 + 257 + /esbuild-linux-64/0.14.54: 258 + resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} 259 + engines: {node: '>=12'} 260 + cpu: [x64] 261 + os: [linux] 262 + requiresBuild: true 263 + dev: true 264 + optional: true 265 + 266 + /esbuild-linux-64/0.15.18: 267 + resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==} 268 + engines: {node: '>=12'} 269 + cpu: [x64] 270 + os: [linux] 271 + requiresBuild: true 272 + dev: true 273 + optional: true 274 + 275 + /esbuild-linux-arm/0.14.54: 276 + resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} 277 + engines: {node: '>=12'} 278 + cpu: [arm] 279 + os: [linux] 280 + requiresBuild: true 281 + dev: true 282 + optional: true 283 + 284 + /esbuild-linux-arm/0.15.18: 285 + resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==} 286 + engines: {node: '>=12'} 287 + cpu: [arm] 288 + os: [linux] 289 + requiresBuild: true 290 + dev: true 291 + optional: true 292 + 293 + /esbuild-linux-arm64/0.14.54: 294 + resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} 295 + engines: {node: '>=12'} 296 + cpu: [arm64] 297 + os: [linux] 298 + requiresBuild: true 299 + dev: true 300 + optional: true 301 + 302 + /esbuild-linux-arm64/0.15.18: 303 + resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==} 304 + engines: {node: '>=12'} 305 + cpu: [arm64] 306 + os: [linux] 307 + requiresBuild: true 308 + dev: true 309 + optional: true 310 + 311 + /esbuild-linux-mips64le/0.14.54: 312 + resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} 313 + engines: {node: '>=12'} 314 + cpu: [mips64el] 315 + os: [linux] 316 + requiresBuild: true 317 + dev: true 318 + optional: true 319 + 320 + /esbuild-linux-mips64le/0.15.18: 321 + resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==} 322 + engines: {node: '>=12'} 323 + cpu: [mips64el] 324 + os: [linux] 325 + requiresBuild: true 326 + dev: true 327 + optional: true 328 + 329 + /esbuild-linux-ppc64le/0.14.54: 330 + resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} 331 + engines: {node: '>=12'} 332 + cpu: [ppc64] 333 + os: [linux] 334 + requiresBuild: true 335 + dev: true 336 + optional: true 337 + 338 + /esbuild-linux-ppc64le/0.15.18: 339 + resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==} 340 + engines: {node: '>=12'} 341 + cpu: [ppc64] 342 + os: [linux] 343 + requiresBuild: true 344 + dev: true 345 + optional: true 346 + 347 + /esbuild-linux-riscv64/0.14.54: 348 + resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} 349 + engines: {node: '>=12'} 350 + cpu: [riscv64] 351 + os: [linux] 352 + requiresBuild: true 353 + dev: true 354 + optional: true 355 + 356 + /esbuild-linux-riscv64/0.15.18: 357 + resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==} 358 + engines: {node: '>=12'} 359 + cpu: [riscv64] 360 + os: [linux] 361 + requiresBuild: true 362 + dev: true 363 + optional: true 364 + 365 + /esbuild-linux-s390x/0.14.54: 366 + resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} 367 + engines: {node: '>=12'} 368 + cpu: [s390x] 369 + os: [linux] 370 + requiresBuild: true 371 + dev: true 372 + optional: true 373 + 374 + /esbuild-linux-s390x/0.15.18: 375 + resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==} 376 + engines: {node: '>=12'} 377 + cpu: [s390x] 378 + os: [linux] 379 + requiresBuild: true 380 + dev: true 381 + optional: true 382 + 383 + /esbuild-netbsd-64/0.14.54: 384 + resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} 385 + engines: {node: '>=12'} 386 + cpu: [x64] 387 + os: [netbsd] 388 + requiresBuild: true 389 + dev: true 390 + optional: true 391 + 392 + /esbuild-netbsd-64/0.15.18: 393 + resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==} 394 + engines: {node: '>=12'} 395 + cpu: [x64] 396 + os: [netbsd] 397 + requiresBuild: true 398 + dev: true 399 + optional: true 400 + 401 + /esbuild-openbsd-64/0.14.54: 402 + resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} 403 + engines: {node: '>=12'} 404 + cpu: [x64] 405 + os: [openbsd] 406 + requiresBuild: true 407 + dev: true 408 + optional: true 409 + 410 + /esbuild-openbsd-64/0.15.18: 411 + resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==} 412 + engines: {node: '>=12'} 413 + cpu: [x64] 414 + os: [openbsd] 415 + requiresBuild: true 416 + dev: true 417 + optional: true 418 + 419 + /esbuild-sunos-64/0.14.54: 420 + resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} 421 + engines: {node: '>=12'} 422 + cpu: [x64] 423 + os: [sunos] 424 + requiresBuild: true 425 + dev: true 426 + optional: true 427 + 428 + /esbuild-sunos-64/0.15.18: 429 + resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==} 430 + engines: {node: '>=12'} 431 + cpu: [x64] 432 + os: [sunos] 433 + requiresBuild: true 434 + dev: true 435 + optional: true 436 + 437 + /esbuild-windows-32/0.14.54: 438 + resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} 439 + engines: {node: '>=12'} 440 + cpu: [ia32] 441 + os: [win32] 442 + requiresBuild: true 443 + dev: true 444 + optional: true 445 + 446 + /esbuild-windows-32/0.15.18: 447 + resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} 448 + engines: {node: '>=12'} 449 + cpu: [ia32] 450 + os: [win32] 451 + requiresBuild: true 452 + dev: true 453 + optional: true 454 + 455 + /esbuild-windows-64/0.14.54: 456 + resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} 457 + engines: {node: '>=12'} 458 + cpu: [x64] 459 + os: [win32] 460 + requiresBuild: true 461 + dev: true 462 + optional: true 463 + 464 + /esbuild-windows-64/0.15.18: 465 + resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==} 466 + engines: {node: '>=12'} 467 + cpu: [x64] 468 + os: [win32] 469 + requiresBuild: true 470 + dev: true 471 + optional: true 472 + 473 + /esbuild-windows-arm64/0.14.54: 474 + resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} 475 + engines: {node: '>=12'} 476 + cpu: [arm64] 477 + os: [win32] 478 + requiresBuild: true 479 + dev: true 480 + optional: true 481 + 482 + /esbuild-windows-arm64/0.15.18: 483 + resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==} 484 + engines: {node: '>=12'} 485 + cpu: [arm64] 486 + os: [win32] 487 + requiresBuild: true 488 + dev: true 489 + optional: true 490 + 491 + /esbuild/0.14.54: 492 + resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} 493 + engines: {node: '>=12'} 494 + hasBin: true 495 + requiresBuild: true 496 + optionalDependencies: 497 + '@esbuild/linux-loong64': 0.14.54 498 + esbuild-android-64: 0.14.54 499 + esbuild-android-arm64: 0.14.54 500 + esbuild-darwin-64: 0.14.54 501 + esbuild-darwin-arm64: 0.14.54 502 + esbuild-freebsd-64: 0.14.54 503 + esbuild-freebsd-arm64: 0.14.54 504 + esbuild-linux-32: 0.14.54 505 + esbuild-linux-64: 0.14.54 506 + esbuild-linux-arm: 0.14.54 507 + esbuild-linux-arm64: 0.14.54 508 + esbuild-linux-mips64le: 0.14.54 509 + esbuild-linux-ppc64le: 0.14.54 510 + esbuild-linux-riscv64: 0.14.54 511 + esbuild-linux-s390x: 0.14.54 512 + esbuild-netbsd-64: 0.14.54 513 + esbuild-openbsd-64: 0.14.54 514 + esbuild-sunos-64: 0.14.54 515 + esbuild-windows-32: 0.14.54 516 + esbuild-windows-64: 0.14.54 517 + esbuild-windows-arm64: 0.14.54 518 + dev: true 519 + 520 + /esbuild/0.15.18: 521 + resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} 522 + engines: {node: '>=12'} 523 + hasBin: true 524 + requiresBuild: true 525 + optionalDependencies: 526 + '@esbuild/android-arm': 0.15.18 527 + '@esbuild/linux-loong64': 0.15.18 528 + esbuild-android-64: 0.15.18 529 + esbuild-android-arm64: 0.15.18 530 + esbuild-darwin-64: 0.15.18 531 + esbuild-darwin-arm64: 0.15.18 532 + esbuild-freebsd-64: 0.15.18 533 + esbuild-freebsd-arm64: 0.15.18 534 + esbuild-linux-32: 0.15.18 535 + esbuild-linux-64: 0.15.18 536 + esbuild-linux-arm: 0.15.18 537 + esbuild-linux-arm64: 0.15.18 538 + esbuild-linux-mips64le: 0.15.18 539 + esbuild-linux-ppc64le: 0.15.18 540 + esbuild-linux-riscv64: 0.15.18 541 + esbuild-linux-s390x: 0.15.18 542 + esbuild-netbsd-64: 0.15.18 543 + esbuild-openbsd-64: 0.15.18 544 + esbuild-sunos-64: 0.15.18 545 + esbuild-windows-32: 0.15.18 546 + esbuild-windows-64: 0.15.18 547 + esbuild-windows-arm64: 0.15.18 548 + dev: true 549 + 550 + /kleur/4.1.5: 551 + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} 552 + engines: {node: '>=6'} 553 + dev: true 554 + 555 + /mri/1.2.0: 556 + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 557 + engines: {node: '>=4'} 558 + dev: true 559 + 560 + /nanospy/0.5.0: 561 + resolution: {integrity: sha512-QxH93ntkjRiSP+gJrBLcgOO3neU6pGhUKjPAJ7rAFag/+tJ+/0lw6dXic+iXUQ/3Cxk4Dp/FwLnf57xnQsjecQ==} 562 + engines: {node: ^8.0.0 || ^10.0.0 || ^12.0.0 || ^14.0.0 || >=16.0.0} 563 + dev: true 564 + 565 + /prettier/2.8.4: 566 + resolution: {integrity: sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==} 567 + engines: {node: '>=10.13.0'} 568 + hasBin: true 569 + dev: true 570 + 571 + /rewrite-imports/2.0.3: 572 + resolution: {integrity: sha512-R7ICJEeP3y+d/q4C8YEJj9nRP0JyiSqG07uc0oQh8JvAe706dDFVL95GBZYCjADqmhArZWWjfM/5EcmVu4/B+g==} 573 + engines: {node: '>=6'} 574 + dev: true 575 + 576 + /sade/1.8.1: 577 + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} 578 + engines: {node: '>=6'} 579 + dependencies: 580 + mri: 1.2.0 581 + dev: true 582 + 583 + /source-map-support/0.5.21: 584 + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 585 + dependencies: 586 + buffer-from: 1.1.2 587 + source-map: 0.6.1 588 + dev: true 589 + 590 + /source-map/0.6.1: 591 + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 592 + engines: {node: '>=0.10.0'} 593 + dev: true 594 + 595 + /terser/5.16.6: 596 + resolution: {integrity: sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg==} 597 + engines: {node: '>=10'} 598 + hasBin: true 599 + dependencies: 600 + '@jridgewell/source-map': 0.3.2 601 + acorn: 8.8.2 602 + commander: 2.20.3 603 + source-map-support: 0.5.21 604 + dev: true 605 + 606 + /tsm/2.3.0: 607 + resolution: {integrity: sha512-++0HFnmmR+gMpDtKTnW3XJ4yv9kVGi20n+NfyQWB9qwJvTaIWY9kBmzek2YUQK5APTQ/1DTrXmm4QtFPmW9Rzw==} 608 + engines: {node: '>=12'} 609 + hasBin: true 610 + dependencies: 611 + esbuild: 0.15.18 612 + dev: true 613 + 614 + /typescript/4.9.5: 615 + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} 616 + engines: {node: '>=4.2.0'} 617 + hasBin: true 618 + dev: true 619 + 620 + /uvu/0.5.6: 621 + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} 622 + engines: {node: '>=8'} 623 + hasBin: true 624 + dependencies: 625 + dequal: 2.0.3 626 + diff: 5.1.0 627 + kleur: 4.1.5 628 + sade: 1.8.1 629 + dev: true
+3
src/index.d.ts
··· 1 + export type LoadFn<T> = (keys: string[]) => Promise<T[]>; 2 + 3 + export function load<T>(loadFn: LoadFn<T>, key: string): Promise<T>;
+187
src/index.spec.ts
··· 1 + import * as assert from 'uvu/assert'; 2 + import { test, suite } from 'uvu'; 3 + import { spy } from 'nanospy'; 4 + 5 + import * as dldr from '.'; 6 + 7 + test('should work', async () => { 8 + const loader = spy((keys: string[]) => Promise.resolve(keys)); 9 + 10 + const items = await Promise.all([ 11 + dldr.load(loader, 'a'), 12 + dldr.load(loader, 'b'), 13 + dldr.load(loader, 'c'), 14 + ]); 15 + 16 + assert.equal(loader.callCount, 1); 17 + assert.equal(items[0], 'a'); 18 + assert.equal(items[1], 'b'); 19 + assert.equal(items[2], 'c'); 20 + }); 21 + 22 + test('maintains call arg order', async () => { 23 + const loader = spy(async (keys: string[]) => keys); 24 + 25 + const prom = Promise.all([ 26 + dldr.load(loader, 'a'), 27 + dldr.load(loader, 'b'), 28 + dldr.load(loader, 'c'), 29 + ]); 30 + 31 + await dldr.load(loader, 'c'); 32 + await prom; 33 + 34 + assert.equal(loader.callCount, 1); 35 + assert.equal(loader.calls[0], [['a', 'b', 'c']]); 36 + }); 37 + 38 + test('new batch once await', async () => { 39 + const loader = spy(async (keys: string[]) => keys); 40 + 41 + const items = await Promise.all([ 42 + dldr.load(loader, 'a'), 43 + dldr.load(loader, 'b'), 44 + dldr.load(loader, 'c'), 45 + ]); 46 + 47 + assert.equal(loader.callCount, 1); 48 + assert.equal(items[0], 'a'); 49 + assert.equal(items[1], 'b'); 50 + assert.equal(items[2], 'c'); 51 + 52 + const items2 = await Promise.all([ 53 + dldr.load(loader, 'd'), 54 + dldr.load(loader, 'e'), 55 + ]); 56 + 57 + assert.equal(loader.callCount, 2); 58 + assert.equal(loader.calls[1], [['d', 'e']]); 59 + assert.equal(items2[0], 'd'); 60 + assert.equal(items2[1], 'e'); 61 + }); 62 + 63 + test('seperate loaders shouldnt mix', async () => { 64 + const loader1 = spy(async (keys: string[]) => keys); 65 + const loader2 = spy(async (keys: string[]) => keys); 66 + 67 + const items = await Promise.all([ 68 + dldr.load(loader1, 'a'), 69 + dldr.load(loader2, 'b'), 70 + dldr.load(loader1, 'c'), 71 + ]); 72 + 73 + assert.equal(loader1.callCount, 1); 74 + assert.equal(loader2.callCount, 1); 75 + assert.equal(loader1.calls[0], [['a', 'c']]); 76 + assert.equal(loader2.calls[0], [['b']]); 77 + assert.equal(items[0], 'a'); 78 + assert.equal(items[1], 'b'); 79 + assert.equal(items[2], 'c'); 80 + }); 81 + 82 + test('should reuse key', async () => { 83 + const loader = spy(async (keys: string[]) => keys); 84 + 85 + const items = await Promise.all([ 86 + dldr.load(loader, 'a'), 87 + dldr.load(loader, 'a'), 88 + dldr.load(loader, 'a'), 89 + ]); 90 + 91 + assert.equal(loader.callCount, 1); 92 + assert.equal(loader.calls[0], [['a']]); 93 + assert.equal(items[0], 'a'); 94 + assert.equal(items[1], 'a'); 95 + assert.equal(items[2], 'a'); 96 + }); 97 + 98 + const errors = suite('errors'); 99 + 100 + const safeThrow = <T>(promise: Promise<T>) => 101 + promise.then( 102 + (value) => ({ value, error: null }), 103 + (error) => ({ value: null, error }), 104 + ); 105 + 106 + errors("reject all load's promises if loader throws", async () => { 107 + const loader = spy(async () => { 108 + throw new Error('error'); 109 + }); 110 + 111 + const items = await Promise.all([ 112 + safeThrow(dldr.load(loader, 'a')), 113 + safeThrow(dldr.load(loader, 'b')), 114 + safeThrow(dldr.load(loader, 'c')), 115 + ]); 116 + 117 + assert.equal(loader.callCount, 1); 118 + assert.equal(items[0].value, null); 119 + assert.instance(items[0].error, Error); 120 + assert.equal(items[1].value, null); 121 + assert.instance(items[1].error, Error); 122 + assert.equal(items[2].value, null); 123 + assert.instance(items[2].error, Error); 124 + }); 125 + 126 + errors('throw if values length mismatch', async () => { 127 + const loader = spy(async (keys: string[]) => keys.slice(0, 1)); 128 + 129 + const items = await Promise.all([ 130 + safeThrow(dldr.load(loader, 'a')), 131 + safeThrow(dldr.load(loader, 'b')), 132 + safeThrow(dldr.load(loader, 'c')), 133 + ]); 134 + 135 + assert.equal(loader.callCount, 1); 136 + assert.equal(loader.calls[0], [['a', 'b', 'c']]); 137 + assert.instance(loader.results[0], Promise); 138 + assert.equal(await loader.results[0], ['a']); 139 + 140 + assert.instance(items[0].error, Error); 141 + assert.instance(items[1].error, Error); 142 + assert.instance(items[2].error, Error); 143 + }); 144 + 145 + errors('reject load if loader rejects that key', async () => { 146 + const loader = spy(async (keys: string[]) => 147 + keys.map((key) => { 148 + if (key === 'b') return new Error('error'); 149 + return key; 150 + }), 151 + ); 152 + 153 + const items = await Promise.all([ 154 + safeThrow(dldr.load(loader, 'a')), 155 + safeThrow(dldr.load(loader, 'b')), 156 + safeThrow(dldr.load(loader, 'c')), 157 + ]); 158 + 159 + assert.equal(loader.callCount, 1); 160 + assert.equal(items[0].value, 'a'); 161 + assert.equal(items[0].error, null); 162 + assert.equal(items[1].value, null); 163 + assert.instance(items[1].error, Error); 164 + assert.equal(items[2].value, 'c'); 165 + assert.equal(items[2].error, null); 166 + }); 167 + 168 + errors('rejects all promises for the same key', async () => { 169 + const loader = spy(async (keys: string[]) => 170 + keys.map((key) => (key === 'a' ? new Error('error') : key)), 171 + ); 172 + 173 + const items = await Promise.all([ 174 + safeThrow(dldr.load(loader, 'a')), 175 + safeThrow(dldr.load(loader, 'b')), 176 + safeThrow(dldr.load(loader, 'a')), 177 + ]); 178 + 179 + assert.equal(loader.callCount, 1); 180 + assert.instance(items[0].error, Error); 181 + assert.equal(items[1].value, 'b'); 182 + assert.equal(items[1].error, null); 183 + assert.instance(items[2].error, Error); 184 + }); 185 + 186 + test.run(); 187 + errors.run();
+52
src/index.ts
··· 1 + import type { LoadFn } from 'dldr'; 2 + 3 + type CB<T> = { 4 + promise: Promise<T>; 5 + resolve: (v: T) => void; 6 + reject: (e: Error) => void; 7 + }; 8 + 9 + const batchContainer = new WeakMap< 10 + LoadFn<any>, 11 + { cb: CB<any>[]; keys: string[] } 12 + >(); 13 + 14 + export function load<T>(loadFn: LoadFn<T>, key: string): Promise<T> { 15 + let batch = batchContainer.get(loadFn); 16 + 17 + if (!batch) { 18 + batchContainer.set(loadFn, (batch = { cb: [], keys: [] })); 19 + 20 + queueMicrotask(() => { 21 + batchContainer.delete(loadFn); 22 + loadFn(batch!.keys) 23 + .then((values) => { 24 + if (values.length !== batch!.keys.length) 25 + throw new Error('loader value length mismatch'); 26 + 27 + for (let i = 0; i < batch!.keys.length; i++) { 28 + const value = values[i]; 29 + const { resolve, reject } = batch!.cb[i]; 30 + if (value instanceof Error) reject(value); 31 + else resolve(value); 32 + } 33 + }) 34 + .catch((error) => { 35 + for (let i = 0; i < batch!.keys.length; i++) 36 + batch!.cb[i].reject(error); 37 + }); 38 + }); 39 + } 40 + 41 + let idx = batch.keys.indexOf(key); 42 + if (!~idx) idx = batch.keys.push(key) - 1; 43 + 44 + // @ts-expect-error we will supply this soon enough 45 + const p = (batch.cb[idx] ||= {}); 46 + if (p.promise) return Promise.resolve(p.promise); 47 + 48 + return (p.promise = new Promise<T>((resolve, reject) => { 49 + p.resolve = resolve; 50 + p.reject = reject; 51 + })); 52 + }
+14
tsconfig.json
··· 1 + { 2 + "extends": "@marais/tsconfig", 3 + "compilerOptions": { 4 + "noEmit": true, 5 + "declaration": false, 6 + "removeComments": false, 7 + "baseUrl": ".", 8 + "paths": { 9 + "dldr": ["src/index.d.ts", "src/index.ts"] 10 + } 11 + }, 12 + "include": ["src"], 13 + "exclude": ["node_modules"] 14 + }