From 0387c595cdaceaf2ac6cbfebc129e4c7575348e0 Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Sat, 1 Apr 2023 04:31:50 +0100 Subject: [PATCH 01/23] start clean again --- examples/sveltekit-sse/.eslintignore | 13 +++++ examples/sveltekit-sse/.eslintrc.cjs | 15 ++++++ examples/sveltekit-sse/.gitignore | 10 ++++ examples/sveltekit-sse/.npmrc | 1 + examples/sveltekit-sse/.prettierignore | 13 +++++ examples/sveltekit-sse/.prettierrc | 9 ++++ examples/sveltekit-sse/README.md | 38 ++++++++++++++ examples/sveltekit-sse/jsconfig.json | 17 ++++++ examples/sveltekit-sse/package.json | 28 ++++++++++ examples/sveltekit-sse/src/app.d.ts | 12 +++++ examples/sveltekit-sse/src/app.html | 12 +++++ .../sveltekit-sse/src/routes/+page.svelte | 2 + examples/sveltekit-sse/static/favicon.png | Bin 0 -> 1571 bytes examples/sveltekit-sse/svelte.config.js | 13 +++++ examples/sveltekit-sse/vite.config.js | 6 +++ pnpm-lock.yaml | 49 +++++++++++++----- 16 files changed, 226 insertions(+), 12 deletions(-) create mode 100644 examples/sveltekit-sse/.eslintignore create mode 100644 examples/sveltekit-sse/.eslintrc.cjs create mode 100644 examples/sveltekit-sse/.gitignore create mode 100644 examples/sveltekit-sse/.npmrc create mode 100644 examples/sveltekit-sse/.prettierignore create mode 100644 examples/sveltekit-sse/.prettierrc create mode 100644 examples/sveltekit-sse/README.md create mode 100644 examples/sveltekit-sse/jsconfig.json create mode 100644 examples/sveltekit-sse/package.json create mode 100644 examples/sveltekit-sse/src/app.d.ts create mode 100644 examples/sveltekit-sse/src/app.html create mode 100644 examples/sveltekit-sse/src/routes/+page.svelte create mode 100644 examples/sveltekit-sse/static/favicon.png create mode 100644 examples/sveltekit-sse/svelte.config.js create mode 100644 examples/sveltekit-sse/vite.config.js diff --git a/examples/sveltekit-sse/.eslintignore b/examples/sveltekit-sse/.eslintignore new file mode 100644 index 0000000..3897265 --- /dev/null +++ b/examples/sveltekit-sse/.eslintignore @@ -0,0 +1,13 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/examples/sveltekit-sse/.eslintrc.cjs b/examples/sveltekit-sse/.eslintrc.cjs new file mode 100644 index 0000000..fab32bf --- /dev/null +++ b/examples/sveltekit-sse/.eslintrc.cjs @@ -0,0 +1,15 @@ +module.exports = { + root: true, + extends: ['eslint:recommended', 'prettier'], + plugins: ['svelte3'], + overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], + parserOptions: { + sourceType: 'module', + ecmaVersion: 2020 + }, + env: { + browser: true, + es2017: true, + node: true + } +}; diff --git a/examples/sveltekit-sse/.gitignore b/examples/sveltekit-sse/.gitignore new file mode 100644 index 0000000..6635cf5 --- /dev/null +++ b/examples/sveltekit-sse/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/examples/sveltekit-sse/.npmrc b/examples/sveltekit-sse/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/examples/sveltekit-sse/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/examples/sveltekit-sse/.prettierignore b/examples/sveltekit-sse/.prettierignore new file mode 100644 index 0000000..3897265 --- /dev/null +++ b/examples/sveltekit-sse/.prettierignore @@ -0,0 +1,13 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/examples/sveltekit-sse/.prettierrc b/examples/sveltekit-sse/.prettierrc new file mode 100644 index 0000000..a77fdde --- /dev/null +++ b/examples/sveltekit-sse/.prettierrc @@ -0,0 +1,9 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100, + "plugins": ["prettier-plugin-svelte"], + "pluginSearchDirs": ["."], + "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] +} diff --git a/examples/sveltekit-sse/README.md b/examples/sveltekit-sse/README.md new file mode 100644 index 0000000..5c91169 --- /dev/null +++ b/examples/sveltekit-sse/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/examples/sveltekit-sse/jsconfig.json b/examples/sveltekit-sse/jsconfig.json new file mode 100644 index 0000000..fe45e13 --- /dev/null +++ b/examples/sveltekit-sse/jsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/examples/sveltekit-sse/package.json b/examples/sveltekit-sse/package.json new file mode 100644 index 0000000..e9b989f --- /dev/null +++ b/examples/sveltekit-sse/package.json @@ -0,0 +1,28 @@ +{ + "name": "sveltekit-sse", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch", + "lint": "prettier --plugin-search-dir . --check . && eslint .", + "format": "prettier --plugin-search-dir . --write ." + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^2.0.0", + "@sveltejs/kit": "^1.5.0", + "eslint": "^8.28.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-svelte3": "^4.0.0", + "prettier": "^2.8.0", + "prettier-plugin-svelte": "^2.8.1", + "svelte": "^3.54.0", + "svelte-check": "^3.0.1", + "typescript": "^5.0.0", + "vite": "^4.2.0" + }, + "type": "module" +} diff --git a/examples/sveltekit-sse/src/app.d.ts b/examples/sveltekit-sse/src/app.d.ts new file mode 100644 index 0000000..f59b884 --- /dev/null +++ b/examples/sveltekit-sse/src/app.d.ts @@ -0,0 +1,12 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface Platform {} + } +} + +export {}; diff --git a/examples/sveltekit-sse/src/app.html b/examples/sveltekit-sse/src/app.html new file mode 100644 index 0000000..effe0d0 --- /dev/null +++ b/examples/sveltekit-sse/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/sveltekit-sse/src/routes/+page.svelte b/examples/sveltekit-sse/src/routes/+page.svelte new file mode 100644 index 0000000..5982b0a --- /dev/null +++ b/examples/sveltekit-sse/src/routes/+page.svelte @@ -0,0 +1,2 @@ +

Welcome to SvelteKit

+

Visit kit.svelte.dev to read the documentation

diff --git a/examples/sveltekit-sse/static/favicon.png b/examples/sveltekit-sse/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..825b9e65af7c104cfb07089bb28659393b4f2097 GIT binary patch literal 1571 zcmV+;2Hg3HP)Px)-AP12RCwC$UE6KzI1p6{F2N z1VK2vi|pOpn{~#djwYcWXTI_im_u^TJgMZ4JMOsSj!0ma>B?-(Hr@X&W@|R-$}W@Z zgj#$x=!~7LGqHW?IO8+*oE1MyDp!G=L0#^lUx?;!fXv@l^6SvTnf^ac{5OurzC#ZMYc20lI%HhX816AYVs1T3heS1*WaWH z%;x>)-J}YB5#CLzU@GBR6sXYrD>Vw(Fmt#|JP;+}<#6b63Ike{Fuo!?M{yEffez;| zp!PfsuaC)>h>-AdbnwN13g*1LowNjT5?+lFVd#9$!8Z9HA|$*6dQ8EHLu}U|obW6f z2%uGv?vr=KNq7YYa2Roj;|zooo<)lf=&2yxM@e`kM$CmCR#x>gI>I|*Ubr({5Y^rb zghxQU22N}F51}^yfDSt786oMTc!W&V;d?76)9KXX1 z+6Okem(d}YXmmOiZq$!IPk5t8nnS{%?+vDFz3BevmFNgpIod~R{>@#@5x9zJKEHLHv!gHeK~n)Ld!M8DB|Kfe%~123&Hz1Z(86nU7*G5chmyDe ziV7$pB7pJ=96hpxHv9rCR29%bLOXlKU<_13_M8x)6;P8E1Kz6G<&P?$P^%c!M5`2` zfY2zg;VK5~^>TJGQzc+33-n~gKt{{of8GzUkWmU110IgI0DLxRIM>0US|TsM=L|@F z0Bun8U!cRB7-2apz=y-7*UxOxz@Z0)@QM)9wSGki1AZ38ceG7Q72z5`i;i=J`ILzL z@iUO?SBBG-0cQuo+an4TsLy-g-x;8P4UVwk|D8{W@U1Zi z!M)+jqy@nQ$p?5tsHp-6J304Q={v-B>66$P0IDx&YT(`IcZ~bZfmn11#rXd7<5s}y zBi9eim&zQc0Dk|2>$bs0PnLmDfMP5lcXRY&cvJ=zKxI^f0%-d$tD!`LBf9^jMSYUA zI8U?CWdY@}cRq6{5~y+)#h1!*-HcGW@+gZ4B};0OnC~`xQOyH19z*TA!!BJ%9s0V3F?CAJ{hTd#*tf+ur-W9MOURF-@B77_-OshsY}6 zOXRY=5%C^*26z?l)1=$bz30!so5tfABdSYzO+H=CpV~aaUefmjvfZ3Ttu9W&W3Iu6 zROlh0MFA5h;my}8lB0tAV-Rvc2Zs_CCSJnx@d`**$idgy-iMob4dJWWw|21b4NB=LfsYp0Aeh{Ov)yztQi;eL4y5 zMi>8^SzKqk8~k?UiQK^^-5d8c%bV?$F8%X~czyiaKCI2=UH= 16} peerDependencies: svelte: ^3.54.0 @@ -1780,7 +1806,7 @@ packages: debug: 4.3.4 deepmerge: 4.3.0 kleur: 4.1.5 - magic-string: 0.29.0 + magic-string: 0.27.0 svelte: 3.57.0 svelte-hmr: 0.15.1_svelte@3.57.0 vite: 4.2.0 @@ -2514,13 +2540,6 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /magic-string/0.29.0: - resolution: {integrity: sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - /magic-string/0.30.0: resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} engines: {node: '>=12'} @@ -3149,6 +3168,12 @@ packages: hasBin: true dev: true + /typescript/5.0.3: + resolution: {integrity: sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==} + engines: {node: '>=12.20'} + hasBin: true + dev: true + /undici/5.21.0: resolution: {integrity: sha512-HOjK8l6a57b2ZGXOcUsI5NLfoTrfmbOl90ixJDl0AEFG4wgHNDQxtZy15/ZQp7HhjkpaGlp/eneMgtsu1dIlUA==} engines: {node: '>=12.18'} From e822fa07d0d30ba71efecefa4a487043f03e324c Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Sat, 1 Apr 2023 04:32:17 +0100 Subject: [PATCH 02/23] update dependencies --- examples/sveltekit-sse/package.json | 18 +- pnpm-lock.yaml | 616 +++++++++++++++++++++++++++- 2 files changed, 603 insertions(+), 31 deletions(-) diff --git a/examples/sveltekit-sse/package.json b/examples/sveltekit-sse/package.json index e9b989f..65c0da4 100644 --- a/examples/sveltekit-sse/package.json +++ b/examples/sveltekit-sse/package.json @@ -13,16 +13,16 @@ }, "devDependencies": { "@sveltejs/adapter-auto": "^2.0.0", - "@sveltejs/kit": "^1.5.0", - "eslint": "^8.28.0", - "eslint-config-prettier": "^8.5.0", + "@sveltejs/kit": "^1.15.0", + "eslint": "^8.37.0", + "eslint-config-prettier": "^8.8.0", "eslint-plugin-svelte3": "^4.0.0", - "prettier": "^2.8.0", - "prettier-plugin-svelte": "^2.8.1", - "svelte": "^3.54.0", - "svelte-check": "^3.0.1", - "typescript": "^5.0.0", - "vite": "^4.2.0" + "prettier": "^2.8.7", + "prettier-plugin-svelte": "^2.10.0", + "svelte": "^3.58.0", + "svelte-check": "^3.1.4", + "typescript": "^5.0.3", + "vite": "^4.2.1" }, "type": "module" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2720e0..6f116c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,28 +100,28 @@ importers: examples/sveltekit-sse: specifiers: '@sveltejs/adapter-auto': ^2.0.0 - '@sveltejs/kit': ^1.5.0 - eslint: ^8.28.0 - eslint-config-prettier: ^8.5.0 + '@sveltejs/kit': ^1.15.0 + eslint: ^8.37.0 + eslint-config-prettier: ^8.8.0 eslint-plugin-svelte3: ^4.0.0 - prettier: ^2.8.0 - prettier-plugin-svelte: ^2.8.1 - svelte: ^3.54.0 - svelte-check: ^3.0.1 - typescript: ^5.0.0 - vite: ^4.2.0 + prettier: ^2.8.7 + prettier-plugin-svelte: ^2.10.0 + svelte: ^3.58.0 + svelte-check: ^3.1.4 + typescript: ^5.0.3 + vite: ^4.2.1 devDependencies: - '@sveltejs/adapter-auto': 2.0.0_@sveltejs+kit@1.12.0 - '@sveltejs/kit': 1.12.0_svelte@3.57.0+vite@4.2.0 - eslint: 8.36.0 - eslint-config-prettier: 8.7.0_eslint@8.36.0 - eslint-plugin-svelte3: 4.0.0_wzem237sbvnwe7n34ytc5phasy - prettier: 2.8.4 - prettier-plugin-svelte: 2.9.0_k23gl6auqwrxgr3e6o2bajswou - svelte: 3.57.0 - svelte-check: 3.1.4_svelte@3.57.0 + '@sveltejs/adapter-auto': 2.0.0_@sveltejs+kit@1.15.0 + '@sveltejs/kit': 1.15.0_svelte@3.58.0+vite@4.2.1 + eslint: 8.37.0 + eslint-config-prettier: 8.8.0_eslint@8.37.0 + eslint-plugin-svelte3: 4.0.0_4gllgxcu6gmiyy5rrmqexpx7de + prettier: 2.8.7 + prettier-plugin-svelte: 2.10.0_ur5pqdgn24bclu6l6i7qojopk4 + svelte: 3.58.0 + svelte-check: 3.1.4_svelte@3.58.0 typescript: 5.0.3 - vite: 4.2.0 + vite: 4.2.1 packages: @@ -1144,6 +1144,15 @@ packages: dev: true optional: true + /@esbuild/android-arm/0.17.14: + resolution: {integrity: sha512-0CnlwnjDU8cks0yJLXfkaU/uoLyRf9VZJs4p1PskBr2AlAHeEsFEwJEo0of/Z3g+ilw5mpyDwThlxzNEIxOE4g==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm64/0.16.17: resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} engines: {node: '>=12'} @@ -1162,6 +1171,15 @@ packages: dev: true optional: true + /@esbuild/android-arm64/0.17.14: + resolution: {integrity: sha512-eLOpPO1RvtsP71afiFTvS7tVFShJBCT0txiv/xjFBo5a7R7Gjw7X0IgIaFoLKhqXYAXhahoXm7qAmRXhY4guJg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64/0.16.17: resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} engines: {node: '>=12'} @@ -1180,6 +1198,15 @@ packages: dev: true optional: true + /@esbuild/android-x64/0.17.14: + resolution: {integrity: sha512-nrfQYWBfLGfSGLvRVlt6xi63B5IbfHm3tZCdu/82zuFPQ7zez4XjmRtF/wIRYbJQ/DsZrxJdEvYFE67avYXyng==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64/0.16.17: resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} engines: {node: '>=12'} @@ -1198,6 +1225,15 @@ packages: dev: true optional: true + /@esbuild/darwin-arm64/0.17.14: + resolution: {integrity: sha512-eoSjEuDsU1ROwgBH/c+fZzuSyJUVXQTOIN9xuLs9dE/9HbV/A5IqdXHU1p2OfIMwBwOYJ9SFVGGldxeRCUJFyw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64/0.16.17: resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} engines: {node: '>=12'} @@ -1216,6 +1252,15 @@ packages: dev: true optional: true + /@esbuild/darwin-x64/0.17.14: + resolution: {integrity: sha512-zN0U8RWfrDttdFNkHqFYZtOH8hdi22z0pFm0aIJPsNC4QQZv7je8DWCX5iA4Zx6tRhS0CCc0XC2m7wKsbWEo5g==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64/0.16.17: resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} engines: {node: '>=12'} @@ -1234,6 +1279,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-arm64/0.17.14: + resolution: {integrity: sha512-z0VcD4ibeZWVQCW1O7szaLxGsx54gcCnajEJMdYoYjLiq4g1jrP2lMq6pk71dbS5+7op/L2Aod+erw+EUr28/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64/0.16.17: resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} engines: {node: '>=12'} @@ -1252,6 +1306,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-x64/0.17.14: + resolution: {integrity: sha512-hd9mPcxfTgJlolrPlcXkQk9BMwNBvNBsVaUe5eNUqXut6weDQH8whcNaKNF2RO8NbpT6GY8rHOK2A9y++s+ehw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm/0.16.17: resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} engines: {node: '>=12'} @@ -1270,6 +1333,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm/0.17.14: + resolution: {integrity: sha512-BNTl+wSJ1omsH8s3TkQmIIIQHwvwJrU9u1ggb9XU2KTVM4TmthRIVyxSp2qxROJHhZuW/r8fht46/QE8hU8Qvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64/0.16.17: resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} engines: {node: '>=12'} @@ -1288,6 +1360,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm64/0.17.14: + resolution: {integrity: sha512-FhAMNYOq3Iblcj9i+K0l1Fp/MHt+zBeRu/Qkf0LtrcFu3T45jcwB6A1iMsemQ42vR3GBhjNZJZTaCe3VFPbn9g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32/0.16.17: resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} engines: {node: '>=12'} @@ -1306,6 +1387,15 @@ packages: dev: true optional: true + /@esbuild/linux-ia32/0.17.14: + resolution: {integrity: sha512-91OK/lQ5y2v7AsmnFT+0EyxdPTNhov3y2CWMdizyMfxSxRqHazXdzgBKtlmkU2KYIc+9ZK3Vwp2KyXogEATYxQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64/0.16.17: resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} engines: {node: '>=12'} @@ -1324,6 +1414,15 @@ packages: dev: true optional: true + /@esbuild/linux-loong64/0.17.14: + resolution: {integrity: sha512-vp15H+5NR6hubNgMluqqKza85HcGJgq7t6rMH7O3Y6ApiOWPkvW2AJfNojUQimfTp6OUrACUXfR4hmpcENXoMQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el/0.16.17: resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} engines: {node: '>=12'} @@ -1342,6 +1441,15 @@ packages: dev: true optional: true + /@esbuild/linux-mips64el/0.17.14: + resolution: {integrity: sha512-90TOdFV7N+fgi6c2+GO9ochEkmm9kBAKnuD5e08GQMgMINOdOFHuYLPQ91RYVrnWwQ5683sJKuLi9l4SsbJ7Hg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64/0.16.17: resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} engines: {node: '>=12'} @@ -1360,6 +1468,15 @@ packages: dev: true optional: true + /@esbuild/linux-ppc64/0.17.14: + resolution: {integrity: sha512-NnBGeoqKkTugpBOBZZoktQQ1Yqb7aHKmHxsw43NddPB2YWLAlpb7THZIzsRsTr0Xw3nqiPxbA1H31ZMOG+VVPQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64/0.16.17: resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} engines: {node: '>=12'} @@ -1378,6 +1495,15 @@ packages: dev: true optional: true + /@esbuild/linux-riscv64/0.17.14: + resolution: {integrity: sha512-0qdlKScLXA8MGVy21JUKvMzCYWovctuP8KKqhtE5A6IVPq4onxXhSuhwDd2g5sRCzNDlDjitc5sX31BzDoL5Fw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x/0.16.17: resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} engines: {node: '>=12'} @@ -1396,6 +1522,15 @@ packages: dev: true optional: true + /@esbuild/linux-s390x/0.17.14: + resolution: {integrity: sha512-Hdm2Jo1yaaOro4v3+6/zJk6ygCqIZuSDJHdHaf8nVH/tfOuoEX5Riv03Ka15LmQBYJObUTNS1UdyoMk0WUn9Ww==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64/0.16.17: resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} engines: {node: '>=12'} @@ -1414,6 +1549,15 @@ packages: dev: true optional: true + /@esbuild/linux-x64/0.17.14: + resolution: {integrity: sha512-8KHF17OstlK4DuzeF/KmSgzrTWQrkWj5boluiiq7kvJCiQVzUrmSkaBvcLB2UgHpKENO2i6BthPkmUhNDaJsVw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64/0.16.17: resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} engines: {node: '>=12'} @@ -1432,6 +1576,15 @@ packages: dev: true optional: true + /@esbuild/netbsd-x64/0.17.14: + resolution: {integrity: sha512-nVwpqvb3yyXztxIT2+VsxJhB5GCgzPdk1n0HHSnchRAcxqKO6ghXwHhJnr0j/B+5FSyEqSxF4q03rbA2fKXtUQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64/0.16.17: resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} engines: {node: '>=12'} @@ -1450,6 +1603,15 @@ packages: dev: true optional: true + /@esbuild/openbsd-x64/0.17.14: + resolution: {integrity: sha512-1RZ7uQQ9zcy/GSAJL1xPdN7NDdOOtNEGiJalg/MOzeakZeTrgH/DoCkbq7TaPDiPhWqnDF+4bnydxRqQD7il6g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64/0.16.17: resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} engines: {node: '>=12'} @@ -1468,6 +1630,15 @@ packages: dev: true optional: true + /@esbuild/sunos-x64/0.17.14: + resolution: {integrity: sha512-nqMjDsFwv7vp7msrwWRysnM38Sd44PKmW8EzV01YzDBTcTWUpczQg6mGao9VLicXSgW/iookNK6AxeogNVNDZA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64/0.16.17: resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} engines: {node: '>=12'} @@ -1486,6 +1657,15 @@ packages: dev: true optional: true + /@esbuild/win32-arm64/0.17.14: + resolution: {integrity: sha512-xrD0mccTKRBBIotrITV7WVQAwNJ5+1va6L0H9zN92v2yEdjfAN7864cUaZwJS7JPEs53bDTzKFbfqVlG2HhyKQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32/0.16.17: resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} engines: {node: '>=12'} @@ -1504,6 +1684,15 @@ packages: dev: true optional: true + /@esbuild/win32-ia32/0.17.14: + resolution: {integrity: sha512-nXpkz9bbJrLLyUTYtRotSS3t5b+FOuljg8LgLdINWFs3FfqZMtbnBCZFUmBzQPyxqU87F8Av+3Nco/M3hEcu1w==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64/0.16.17: resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} engines: {node: '>=12'} @@ -1522,6 +1711,15 @@ packages: dev: true optional: true + /@esbuild/win32-x64/0.17.14: + resolution: {integrity: sha512-gPQmsi2DKTaEgG14hc3CHXHp62k8g6qr0Pas+I4lUxRMugGSATh/Bi8Dgusoz9IQ0IfdrvLpco6kujEIBoaogA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@eslint-community/eslint-utils/4.2.0_eslint@8.36.0: resolution: {integrity: sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1532,11 +1730,26 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /@eslint-community/eslint-utils/4.4.0_eslint@8.37.0: + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.37.0 + eslint-visitor-keys: 3.4.0 + dev: true + /@eslint-community/regexpp/4.4.0: resolution: {integrity: sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true + /@eslint-community/regexpp/4.5.0: + resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + /@eslint/eslintrc/2.0.1: resolution: {integrity: sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1554,11 +1767,33 @@ packages: - supports-color dev: true + /@eslint/eslintrc/2.0.2: + resolution: {integrity: sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.5.1 + globals: 13.20.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + /@eslint/js/8.36.0: resolution: {integrity: sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@eslint/js/8.37.0: + resolution: {integrity: sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@humanwhocodes/config-array/0.11.8: resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} engines: {node: '>=10.10.0'} @@ -1693,6 +1928,15 @@ packages: import-meta-resolve: 2.2.2 dev: true + /@sveltejs/adapter-auto/2.0.0_@sveltejs+kit@1.15.0: + resolution: {integrity: sha512-b+gkHFZgD771kgV3aO4avHFd7y1zhmMYy9i6xOK7m/rwmwaRO8gnF5zBc0Rgca80B2PMU1bKNxyBTHA14OzUAQ==} + peerDependencies: + '@sveltejs/kit': ^1.0.0 + dependencies: + '@sveltejs/kit': 1.15.0_svelte@3.58.0+vite@4.2.1 + import-meta-resolve: 2.2.2 + dev: true + /@sveltejs/adapter-node/1.2.3_@sveltejs+kit@1.12.0: resolution: {integrity: sha512-Fv6NyVpVWYA63KRaV6dDjcU8ytcWFiUr0siJOoHl+oWy5WHNEuRiJOUdiZzYbZo8MmvFaCoxHkTgPrVQhpqaRA==} peerDependencies: @@ -1761,6 +2005,34 @@ packages: - supports-color dev: true + /@sveltejs/kit/1.15.0_svelte@3.58.0+vite@4.2.1: + resolution: {integrity: sha512-fvDsW9msxWjDU/j9wwLlxEZ6cpXQYcmcQHq7neJMqibMEl39gI1ztVymGnYqM8KLqZXwNmhKtLu8EPheukKtXQ==} + engines: {node: ^16.14 || >=18} + hasBin: true + requiresBuild: true + peerDependencies: + svelte: ^3.54.0 + vite: ^4.0.0 + dependencies: + '@sveltejs/vite-plugin-svelte': 2.0.4_svelte@3.58.0+vite@4.2.1 + '@types/cookie': 0.5.1 + cookie: 0.5.0 + devalue: 4.3.0 + esm-env: 1.0.0 + kleur: 4.1.5 + magic-string: 0.30.0 + mime: 3.0.0 + sade: 1.8.1 + set-cookie-parser: 2.6.0 + sirv: 2.0.2 + svelte: 3.58.0 + tiny-glob: 0.2.9 + undici: 5.21.0 + vite: 4.2.1 + transitivePeerDependencies: + - supports-color + dev: true + /@sveltejs/package/2.0.1_wkdgp32a7s6524odeddpfzb52q: resolution: {integrity: sha512-DkDQrNTNSdGpE9u03tXr+K6BXfdw1jQfmU1EtmXv3o1+OzWei/866wp+1lCAI+8A2bpjAuCNgvI3j0Sy+glhwQ==} engines: {node: ^16.14 || >=18} @@ -1815,6 +2087,25 @@ packages: - supports-color dev: true + /@sveltejs/vite-plugin-svelte/2.0.4_svelte@3.58.0+vite@4.2.1: + resolution: {integrity: sha512-pjqhW00KwK2uzDGEr+yJBwut+D+4XfJO/+bHHdHzPRXn9+1Jeq5JcFHyrUiYaXgHtyhX0RsllCTm4ssAx4ZY7Q==} + engines: {node: ^14.18.0 || >= 16} + peerDependencies: + svelte: ^3.54.0 + vite: ^4.0.0 + dependencies: + debug: 4.3.4 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.0 + svelte: 3.58.0 + svelte-hmr: 0.15.1_svelte@3.58.0 + vite: 4.2.1 + vitefu: 0.2.4_vite@4.2.1 + transitivePeerDependencies: + - supports-color + dev: true + /@types/cookie/0.5.1: resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} dev: true @@ -2020,6 +2311,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /deepmerge/4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + /detect-indent/6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -2100,6 +2396,36 @@ packages: '@esbuild/win32-x64': 0.17.11 dev: true + /esbuild/0.17.14: + resolution: {integrity: sha512-vOO5XhmVj/1XQR9NQ1UPq6qvMYL7QFJU57J5fKBKBKxp17uDt5PgxFDb4A2nEiXhr1qQs4x0F5+66hVVw4ruNw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.14 + '@esbuild/android-arm64': 0.17.14 + '@esbuild/android-x64': 0.17.14 + '@esbuild/darwin-arm64': 0.17.14 + '@esbuild/darwin-x64': 0.17.14 + '@esbuild/freebsd-arm64': 0.17.14 + '@esbuild/freebsd-x64': 0.17.14 + '@esbuild/linux-arm': 0.17.14 + '@esbuild/linux-arm64': 0.17.14 + '@esbuild/linux-ia32': 0.17.14 + '@esbuild/linux-loong64': 0.17.14 + '@esbuild/linux-mips64el': 0.17.14 + '@esbuild/linux-ppc64': 0.17.14 + '@esbuild/linux-riscv64': 0.17.14 + '@esbuild/linux-s390x': 0.17.14 + '@esbuild/linux-x64': 0.17.14 + '@esbuild/netbsd-x64': 0.17.14 + '@esbuild/openbsd-x64': 0.17.14 + '@esbuild/sunos-x64': 0.17.14 + '@esbuild/win32-arm64': 0.17.14 + '@esbuild/win32-ia32': 0.17.14 + '@esbuild/win32-x64': 0.17.14 + dev: true + /escape-string-regexp/4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -2114,6 +2440,25 @@ packages: eslint: 8.36.0 dev: true + /eslint-config-prettier/8.8.0_eslint@8.37.0: + resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.37.0 + dev: true + + /eslint-plugin-svelte3/4.0.0_4gllgxcu6gmiyy5rrmqexpx7de: + resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==} + peerDependencies: + eslint: '>=8.0.0' + svelte: ^3.2.0 + dependencies: + eslint: 8.37.0 + svelte: 3.58.0 + dev: true + /eslint-plugin-svelte3/4.0.0_wzem237sbvnwe7n34ytc5phasy: resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==} peerDependencies: @@ -2137,6 +2482,11 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /eslint-visitor-keys/3.4.0: + resolution: {integrity: sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /eslint/8.36.0: resolution: {integrity: sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2186,6 +2536,55 @@ packages: - supports-color dev: true + /eslint/8.37.0: + resolution: {integrity: sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0_eslint@8.37.0 + '@eslint-community/regexpp': 4.5.0 + '@eslint/eslintrc': 2.0.2 + '@eslint/js': 8.37.0 + '@humanwhocodes/config-array': 0.11.8 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-visitor-keys: 3.4.0 + espree: 9.5.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.20.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.4 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-sdsl: 4.4.0 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + /esm-env/1.0.0: resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} dev: true @@ -2199,6 +2598,15 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /espree/9.5.1: + resolution: {integrity: sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.2 + acorn-jsx: 5.3.2_acorn@8.8.2 + eslint-visitor-keys: 3.4.0 + dev: true + /esquery/1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} @@ -2488,6 +2896,10 @@ packages: resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==} dev: true + /js-sdsl/4.4.0: + resolution: {integrity: sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==} + dev: true + /js-yaml/4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -2609,8 +3021,8 @@ packages: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true - /nanoid/3.3.4: - resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + /nanoid/3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true @@ -2732,7 +3144,7 @@ packages: resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.4 + nanoid: 3.3.6 picocolors: 1.0.0 source-map-js: 1.0.2 dev: true @@ -2742,6 +3154,16 @@ packages: engines: {node: '>= 0.8.0'} dev: true + /prettier-plugin-svelte/2.10.0_ur5pqdgn24bclu6l6i7qojopk4: + resolution: {integrity: sha512-GXMY6t86thctyCvQq+jqElO+MKdB09BkL3hexyGP3Oi8XLKRFaJP1ud/xlWCZ9ZIa2BxHka32zhHfcuU+XsRQg==} + peerDependencies: + prettier: ^1.16.4 || ^2.0.0 + svelte: ^3.2.0 + dependencies: + prettier: 2.8.7 + svelte: 3.58.0 + dev: true + /prettier-plugin-svelte/2.9.0_k23gl6auqwrxgr3e6o2bajswou: resolution: {integrity: sha512-3doBi5NO4IVgaNPtwewvrgPpqAcvNv0NwJNflr76PIGgi9nf1oguQV1Hpdm9TI2ALIQVn/9iIwLpBO5UcD2Jiw==} peerDependencies: @@ -2758,6 +3180,12 @@ packages: hasBin: true dev: true + /prettier/2.8.7: + resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + /publint/0.1.9: resolution: {integrity: sha512-O53y7vbePxuGFmEjgcrafMSlDpOJwOkj8YdexOt7yWlv7SB3rXoT3mHknyMJ3lf2UFH5Bmt6tnIkHcOTR6dEoA==} engines: {node: '>=16'} @@ -2833,6 +3261,14 @@ packages: fsevents: 2.3.2 dev: true + /rollup/3.20.2: + resolution: {integrity: sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -2869,6 +3305,10 @@ packages: resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==} dev: true + /set-cookie-parser/2.6.0: + resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} + dev: true + /shebang-command/2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2999,6 +3439,33 @@ packages: - sugarss dev: true + /svelte-check/3.1.4_svelte@3.58.0: + resolution: {integrity: sha512-25Lb46ZS4IK/XpBMe4IBMrtYf23V8alqBX+szXoccb7uM0D2Wqq5rMRzYBONZnFVuU1bQG3R50lyIT5eRewv2g==} + hasBin: true + peerDependencies: + svelte: ^3.55.0 + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + chokidar: 3.5.3 + fast-glob: 3.2.12 + import-fresh: 3.3.0 + picocolors: 1.0.0 + sade: 1.8.1 + svelte: 3.58.0 + svelte-preprocess: 5.0.3_aswnnyxiuwffgztcffmr7c7eny + typescript: 4.9.5 + transitivePeerDependencies: + - '@babel/core' + - coffeescript + - less + - postcss + - postcss-load-config + - pug + - sass + - stylus + - sugarss + dev: true + /svelte-hmr/0.15.1_svelte@3.57.0: resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} engines: {node: ^12.20 || ^14.13.1 || >= 16} @@ -3008,6 +3475,15 @@ packages: svelte: 3.57.0 dev: true + /svelte-hmr/0.15.1_svelte@3.58.0: + resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} + engines: {node: ^12.20 || ^14.13.1 || >= 16} + peerDependencies: + svelte: '>=3.19.0' + dependencies: + svelte: 3.58.0 + dev: true + /svelte-preprocess/5.0.1_wkdgp32a7s6524odeddpfzb52q: resolution: {integrity: sha512-0HXyhCoc9rsW4zGOgtInylC6qj259E1hpFnJMJWTf+aIfeqh4O/QHT31KT2hvPEqQfdjmqBR/kO2JDkkciBLrQ==} engines: {node: '>= 14.10.0'} @@ -3103,11 +3579,63 @@ packages: typescript: 4.9.5 dev: true + /svelte-preprocess/5.0.3_aswnnyxiuwffgztcffmr7c7eny: + resolution: {integrity: sha512-GrHF1rusdJVbOZOwgPWtpqmaexkydznKzy5qIC2FabgpFyKN57bjMUUUqPRfbBXK5igiEWn1uO/DXsa2vJ5VHA==} + engines: {node: '>= 14.10.0'} + requiresBuild: true + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + postcss: ^7 || ^8 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 + pug: ^3.0.0 + sass: ^1.26.8 + stylus: ^0.55.0 + sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 + svelte: ^3.23.0 + typescript: '>=3.9.5 || ^4.0.0 || ^5.0.0' + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + dependencies: + '@types/pug': 2.0.6 + detect-indent: 6.1.0 + magic-string: 0.27.0 + sorcery: 0.11.0 + strip-indent: 3.0.0 + svelte: 3.58.0 + typescript: 4.9.5 + dev: true + /svelte/3.57.0: resolution: {integrity: sha512-WMXEvF+RtAaclw0t3bPDTUe19pplMlfyKDsixbHQYgCWi9+O9VN0kXU1OppzrB9gPAvz4NALuoca2LfW2bOjTQ==} engines: {node: '>= 8'} dev: true + /svelte/3.58.0: + resolution: {integrity: sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==} + engines: {node: '>= 8'} + dev: true + /svelte2tsx/0.6.1_wkdgp32a7s6524odeddpfzb52q: resolution: {integrity: sha512-O/1+5UyChfmhp1/GUv8b8iveTrn6eZwHxEXc+rw7LMKRidr9KHk5w/EiliLjDUwHa2VA6CoEty+CQylROVU4Sw==} peerDependencies: @@ -3258,6 +3786,39 @@ packages: fsevents: 2.3.2 dev: true + /vite/4.2.1: + resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.17.14 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.20.2 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /vitefu/0.2.4_vite@4.1.3: resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} peerDependencies: @@ -3280,6 +3841,17 @@ packages: vite: 4.2.0 dev: true + /vitefu/0.2.4_vite@4.2.1: + resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 4.2.1 + dev: true + /which/2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} From 8680566015686ea50d7b0bdc3bf52bae8c56afb5 Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 09:35:07 +0100 Subject: [PATCH 03/23] implement SSE manager --- .../src/lib/sse-manager.server.js | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 examples/sveltekit-sse/src/lib/sse-manager.server.js diff --git a/examples/sveltekit-sse/src/lib/sse-manager.server.js b/examples/sveltekit-sse/src/lib/sse-manager.server.js new file mode 100644 index 0000000..30c144a --- /dev/null +++ b/examples/sveltekit-sse/src/lib/sse-manager.server.js @@ -0,0 +1,116 @@ +/** + * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format + * @typedef {Object} Message - + * @property {string} data - The data field for the message. + * @property {string} [event] - A string identifying the type of event described. If this is specified, an event will be dispatched on the browser to the listener for the specified event name; the website source code should use addEventListener() to listen for named events. The onmessage handler is called if no event name is specified for a message. + * @property {string | number} [id] - The event ID to set the EventSource object's last event ID value. + * @property {number} [retry] - The reconnection time. If the connection to the server is lost, the browser will wait for the specified time before attempting to reconnect. This must be an integer, specifying the reconnection time in milliseconds. + */ + +/** @param {Message} message */ +function create_message_string(message) { + return ( + Object.entries(message) + .map(([key, value]) => `${key}: ${value}`) + .join('\n') + '\n\n' + ); +} + +function create_sse({ max_clients = 1_000, max_connections_per_client = 3 } = {}) { + /** @type {Map>} */ + const clients = new Map(); + /** @type {Set<(client_id: string | number, controllers: Set) => void>} */ + const on_connect_listeners = new Set(); + /** @type {Set<(client_id: string | number, controllers: Set) => void>} */ + const on_disconnect_listeners = new Set(); + + return { + /** + * @param {string | number} client_id + * @returns {ReadableStream | void} + */ + connect(client_id) { + if (clients.size >= max_clients) { + return; + } + + if (clients.has(client_id) === false) { + clients.set(client_id, new Set()); + } + + const controllers = /** @type {Set} */ ( + clients.get(client_id) + ); + + if (controllers.size >= max_connections_per_client) { + return; + } + + /** @type {ReadableStreamDefaultController} */ + let controller; + + const stream = new ReadableStream({ + start(_controller) { + controller = _controller; + controllers.add(controller); + + on_connect_listeners.forEach((fn) => fn(client_id, controllers)); + }, + cancel() { + controllers.delete(controller); + + if (controllers.size === 0) { + clients.delete(client_id); + } + + on_disconnect_listeners.forEach((fn) => fn(client_id, controllers)); + } + }); + + return stream; + }, + + /** @param {(client_id: string | number, controllers: Set) => void} fn */ + on_connect(fn) { + on_connect_listeners.add(fn); + }, + + /** @param {(client_id: string | number, controllers: Set) => void} fn */ + on_disconnect(fn) { + on_disconnect_listeners.add(fn); + }, + + /** + * @param {string | number} client_id + * @param {Message} message + */ + emit_to(client_id, message) { + /** @type {Set | undefined} */ + const controllers = clients.get(client_id); + + if (!controllers) return; + + const message_string = create_message_string(message); + + controllers.forEach((c) => c.enqueue(message_string)); + }, + + /** + * @param {Message} message + * @param {Array} [exclude=[]] + */ + emit_to_all(message, exclude = []) { + const message_string = create_message_string(message); + + for (const [client_id, controllers] of clients) { + if (exclude.includes(client_id)) continue; + + controllers.forEach((c) => c.enqueue(message_string)); + } + } + }; +} + +const sse = create_sse(); + +export default sse; From 4a9de7194ed5bd67bc9754b934b03841e88f4d65 Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 09:38:56 +0100 Subject: [PATCH 04/23] improve typings --- .../src/lib/sse-manager.server.js | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/sveltekit-sse/src/lib/sse-manager.server.js b/examples/sveltekit-sse/src/lib/sse-manager.server.js index 30c144a..efb515d 100644 --- a/examples/sveltekit-sse/src/lib/sse-manager.server.js +++ b/examples/sveltekit-sse/src/lib/sse-manager.server.js @@ -1,12 +1,18 @@ /** - * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format - * @typedef {Object} Message - + * @typedef {Object} Message - https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format * @property {string} data - The data field for the message. * @property {string} [event] - A string identifying the type of event described. If this is specified, an event will be dispatched on the browser to the listener for the specified event name; the website source code should use addEventListener() to listen for named events. The onmessage handler is called if no event name is specified for a message. * @property {string | number} [id] - The event ID to set the EventSource object's last event ID value. * @property {number} [retry] - The reconnection time. If the connection to the server is lost, the browser will wait for the specified time before attempting to reconnect. This must be an integer, specifying the reconnection time in milliseconds. */ +/** + * @callback ConnectionCallback + * @param {string | number} client_id + * @param {Set} controllers + * @returns {void} + */ + /** @param {Message} message */ function create_message_string(message) { return ( @@ -16,12 +22,12 @@ function create_message_string(message) { ); } -function create_sse({ max_clients = 1_000, max_connections_per_client = 3 } = {}) { +function create_sse_manager({ max_clients = 1_000, max_connections_per_client = 3 } = {}) { /** @type {Map>} */ const clients = new Map(); - /** @type {Set<(client_id: string | number, controllers: Set) => void>} */ + /** @type {Set} */ const on_connect_listeners = new Set(); - /** @type {Set<(client_id: string | number, controllers: Set) => void>} */ + /** @type {Set} */ const on_disconnect_listeners = new Set(); return { @@ -70,12 +76,12 @@ function create_sse({ max_clients = 1_000, max_connections_per_client = 3 } = {} return stream; }, - /** @param {(client_id: string | number, controllers: Set) => void} fn */ + /** @param {ConnectionCallback} fn */ on_connect(fn) { on_connect_listeners.add(fn); }, - /** @param {(client_id: string | number, controllers: Set) => void} fn */ + /** @param {ConnectionCallback} fn */ on_disconnect(fn) { on_disconnect_listeners.add(fn); }, @@ -111,6 +117,6 @@ function create_sse({ max_clients = 1_000, max_connections_per_client = 3 } = {} }; } -const sse = create_sse(); +const sse_manager = create_sse_manager(); -export default sse; +export default sse_manager; From 2d044a5385ca7ed0cf6da48059c26bd8939bfd05 Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 09:39:59 +0100 Subject: [PATCH 05/23] improve wording and var names --- .../src/lib/sse-manager.server.js | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/sveltekit-sse/src/lib/sse-manager.server.js b/examples/sveltekit-sse/src/lib/sse-manager.server.js index efb515d..29cbe74 100644 --- a/examples/sveltekit-sse/src/lib/sse-manager.server.js +++ b/examples/sveltekit-sse/src/lib/sse-manager.server.js @@ -26,9 +26,9 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = /** @type {Map>} */ const clients = new Map(); /** @type {Set} */ - const on_connect_listeners = new Set(); + const on_connected_listeners = new Set(); /** @type {Set} */ - const on_disconnect_listeners = new Set(); + const on_disconnected_listeners = new Set(); return { /** @@ -60,7 +60,7 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = controller = _controller; controllers.add(controller); - on_connect_listeners.forEach((fn) => fn(client_id, controllers)); + on_connected_listeners.forEach((cb) => cb(client_id, controllers)); }, cancel() { controllers.delete(controller); @@ -69,21 +69,21 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = clients.delete(client_id); } - on_disconnect_listeners.forEach((fn) => fn(client_id, controllers)); + on_disconnected_listeners.forEach((cb) => cb(client_id, controllers)); } }); return stream; }, - /** @param {ConnectionCallback} fn */ - on_connect(fn) { - on_connect_listeners.add(fn); + /** @param {ConnectionCallback} cb */ + on_connect(cb) { + on_connected_listeners.add(cb); }, - /** @param {ConnectionCallback} fn */ - on_disconnect(fn) { - on_disconnect_listeners.add(fn); + /** @param {ConnectionCallback} cb */ + on_disconnect(cb) { + on_disconnected_listeners.add(cb); }, /** From 26066f4835672a85393128728fed185aa89647f1 Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 10:26:02 +0100 Subject: [PATCH 06/23] rename variables --- examples/sveltekit-sse/src/lib/sse-manager.server.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/sveltekit-sse/src/lib/sse-manager.server.js b/examples/sveltekit-sse/src/lib/sse-manager.server.js index 29cbe74..5c3d756 100644 --- a/examples/sveltekit-sse/src/lib/sse-manager.server.js +++ b/examples/sveltekit-sse/src/lib/sse-manager.server.js @@ -26,9 +26,9 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = /** @type {Map>} */ const clients = new Map(); /** @type {Set} */ - const on_connected_listeners = new Set(); + const on_connected_callbacks = new Set(); /** @type {Set} */ - const on_disconnected_listeners = new Set(); + const on_disconnected_callbacks = new Set(); return { /** @@ -60,7 +60,7 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = controller = _controller; controllers.add(controller); - on_connected_listeners.forEach((cb) => cb(client_id, controllers)); + on_connected_callbacks.forEach((cb) => cb(client_id, controllers)); }, cancel() { controllers.delete(controller); @@ -69,7 +69,7 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = clients.delete(client_id); } - on_disconnected_listeners.forEach((cb) => cb(client_id, controllers)); + on_disconnected_callbacks.forEach((cb) => cb(client_id, controllers)); } }); @@ -78,12 +78,12 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = /** @param {ConnectionCallback} cb */ on_connect(cb) { - on_connected_listeners.add(cb); + on_connected_callbacks.add(cb); }, /** @param {ConnectionCallback} cb */ on_disconnect(cb) { - on_disconnected_listeners.add(cb); + on_disconnected_callbacks.add(cb); }, /** From cf141839977eeb057a4b102fcfe72a3a713eefbd Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 10:32:50 +0100 Subject: [PATCH 07/23] add get_clients function to sse manager --- examples/sveltekit-sse/src/lib/sse-manager.server.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/sveltekit-sse/src/lib/sse-manager.server.js b/examples/sveltekit-sse/src/lib/sse-manager.server.js index 5c3d756..024c8ac 100644 --- a/examples/sveltekit-sse/src/lib/sse-manager.server.js +++ b/examples/sveltekit-sse/src/lib/sse-manager.server.js @@ -113,6 +113,10 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = controllers.forEach((c) => c.enqueue(message_string)); } + }, + + get_clients() { + return clients; } }; } From 14196b746d2800421d6e6f11dba5557ed33cb4ca Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 11:19:37 +0100 Subject: [PATCH 08/23] allow emitting events to arrays of `client_id`s --- .../sveltekit-sse/src/lib/sse-manager.server.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/examples/sveltekit-sse/src/lib/sse-manager.server.js b/examples/sveltekit-sse/src/lib/sse-manager.server.js index 024c8ac..e3f05b6 100644 --- a/examples/sveltekit-sse/src/lib/sse-manager.server.js +++ b/examples/sveltekit-sse/src/lib/sse-manager.server.js @@ -87,18 +87,21 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = }, /** - * @param {string | number} client_id + * @param {string | number | Array} client_id * @param {Message} message */ emit_to(client_id, message) { - /** @type {Set | undefined} */ - const controllers = clients.get(client_id); - - if (!controllers) return; + const client_ids = Array.isArray(client_id) ? client_id : [client_id]; const message_string = create_message_string(message); + + for (const client_id of client_ids) { + const controllers = clients.get(client_id); + + if (!controllers) continue; - controllers.forEach((c) => c.enqueue(message_string)); + controllers.forEach((c) => c.enqueue(message_string)); + } }, /** From 2a22bad50f4dc87dac0d2f5cdae51827f576981d Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 22:05:48 +0100 Subject: [PATCH 09/23] add basic page and store --- examples/sveltekit-sse/src/lib/global.css | 106 ++++++++++++++++++ examples/sveltekit-sse/src/lib/sse-store.js | 46 ++++++++ .../sveltekit-sse/src/routes/+page.server.js | 19 ++++ .../sveltekit-sse/src/routes/+page.svelte | 83 +++++++++++++- .../sveltekit-sse/src/routes/sse/+server.js | 40 +++++++ 5 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 examples/sveltekit-sse/src/lib/global.css create mode 100644 examples/sveltekit-sse/src/lib/sse-store.js create mode 100644 examples/sveltekit-sse/src/routes/+page.server.js create mode 100644 examples/sveltekit-sse/src/routes/sse/+server.js diff --git a/examples/sveltekit-sse/src/lib/global.css b/examples/sveltekit-sse/src/lib/global.css new file mode 100644 index 0000000..f006da6 --- /dev/null +++ b/examples/sveltekit-sse/src/lib/global.css @@ -0,0 +1,106 @@ +/* RESET */ + +*, +*::before, +*::after { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +html, +body { + height: 100%; + font-family: sans-serif; +} + +html:focus-within { + scroll-behavior: smooth; +} + +body { + line-height: 1.5; +} + +a:not([class]) { + text-decoration-skip-ink: auto; +} + +img, +picture, +video, +canvas { + display: block; + max-width: 100%; +} + +input, +button, +textarea, +select, +input[type='file']::file-selector-button { + font: inherit; +} + +label, +textarea, +progress, +input:where( + [type='email'], + [type='password'], + [type='search'], + [type='tel'], + [type='text'], + [type='url'], + [type='file'] + ) { + display: block; + width: 100%; +} + +textarea { + box-sizing: content-box; + min-height: 5em; + resize: block; + resize: vertical; +} + +/* THEME */ + +h1 { + margin-block-start: 3rem; + margin-block-end: 2rem; +} + +h2, +h3 { + margin-block-start: 2rem; + margin-block-end: 1rem; +} + +label { + font-weight: 700; + margin-block-end: 0.25rem; +} + +button, +input[type='file']::file-selector-button { + padding-inline: 0.5rem; + padding-block: 0.2rem; + cursor: pointer; +} + +button:hover { + filter: brightness(1.1); +} + +button.--loading { + cursor: wait; + opacity: 0.6; +} + +.box { + padding: 1rem; + border-radius: 7px; + background-color: hsla(0, 0%, 0%, 0.07); +} diff --git a/examples/sveltekit-sse/src/lib/sse-store.js b/examples/sveltekit-sse/src/lib/sse-store.js new file mode 100644 index 0000000..1b3758a --- /dev/null +++ b/examples/sveltekit-sse/src/lib/sse-store.js @@ -0,0 +1,46 @@ +import { browser } from '$app/environment'; +import { writable } from 'svelte/store'; + +function create_sse_store() { + /** @type {EventSource | undefined} */ + let event_source; + + const { subscribe, update } = writable({ clients: [], messages: [] }, () => { + if (browser) { + connect(); + } + + return close; + }); + + function connect() { + event_source = new EventSource('/sse'); + + event_source.addEventListener('client:list', (event) => { + const { clients } = JSON.parse(event.data); + + update((value) => ({ ...value, clients })); + }); + + event_source.addEventListener('client:message', (event) => { + const json = JSON.parse(event.data); + + update((value) => { + value.messages.push(json); + return value; + }); + }); + } + + function close() { + event_source?.close(); + } + + return { + subscribe + }; +} + +const sse_store = create_sse_store(); + +export default sse_store; diff --git a/examples/sveltekit-sse/src/routes/+page.server.js b/examples/sveltekit-sse/src/routes/+page.server.js new file mode 100644 index 0000000..0c04240 --- /dev/null +++ b/examples/sveltekit-sse/src/routes/+page.server.js @@ -0,0 +1,19 @@ +import sse from '$lib/sse-manager.server.js'; + +/** @type {import('./$types').Actions} */ +export const actions = { + async emit_to_all(event) { + const data = await event.request.formData(); + + const message = JSON.stringify({ text: data.get('text') }); + + sse.emit_to_all({ event: 'message', data: message }); + }, + async emit_to(event) { + const data = await event.request.formData(); + + const message = JSON.stringify({ text: data.get('text') }); + + sse.emit_to(data.get('client_id'), { event: 'message', data: message }); + } +}; diff --git a/examples/sveltekit-sse/src/routes/+page.svelte b/examples/sveltekit-sse/src/routes/+page.svelte index 5982b0a..e7d35a3 100644 --- a/examples/sveltekit-sse/src/routes/+page.svelte +++ b/examples/sveltekit-sse/src/routes/+page.svelte @@ -1,2 +1,81 @@ -

Welcome to SvelteKit

-

Visit kit.svelte.dev to read the documentation

+ + +
+

SvelteKit SSE Example

+ +
+

Send a message to all connected clients

+
+
+ + +
+ +
+
+ +

Connected clients

+ +
    + {#each $sse.clients as client_id (client_id)} +
  • +

    + Client ID: {client_id} +

    + +
    +
    + + +
    + + +
    +
  • + {/each} +
+ +
    + {#each $sse.messages as message (message)} +
  1. {message.text}
  2. + {/each} +
+
+ + diff --git a/examples/sveltekit-sse/src/routes/sse/+server.js b/examples/sveltekit-sse/src/routes/sse/+server.js new file mode 100644 index 0000000..ba0e56f --- /dev/null +++ b/examples/sveltekit-sse/src/routes/sse/+server.js @@ -0,0 +1,40 @@ +import sse from '$lib/sse-manager.server.js'; + +sse.on_connect((client_id, controllers) => { + // Send a list of all currently connected users to the user + const clients = Array.from(sse.get_clients().keys()); + + console.log(clients); + + sse.emit_to_all({ + event: 'client:list', + data: JSON.stringify({ clients }) + }); +}); + +// If the user has closed all connected tabs +// send a message to all other users +sse.on_disconnect((client_id, controllers) => { + if (controllers.size > 0) return; + + const message = { event: 'client:disconnected', data: JSON.stringify({ client_id }) }; + + sse.emit_to_all(message); +}); + +/** @type {import('./$types').RequestHandler} */ +export async function GET() { + const id = crypto.randomUUID(); + + const stream = sse.connect(id); + + if (!stream) { + return new Response(null, { status: 503 }); + } + + return new Response(stream, { + headers: { + 'Content-Type': 'text/event-stream' + } + }); +} From b5739b8121917fa64cd2419a90f9b96f52c145b7 Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 22:50:50 +0100 Subject: [PATCH 10/23] fix function names --- .../sveltekit-sse/src/lib/sse-manager.server.js | 4 ++-- examples/sveltekit-sse/src/routes/sse/+server.js | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/sveltekit-sse/src/lib/sse-manager.server.js b/examples/sveltekit-sse/src/lib/sse-manager.server.js index e3f05b6..bc2eb76 100644 --- a/examples/sveltekit-sse/src/lib/sse-manager.server.js +++ b/examples/sveltekit-sse/src/lib/sse-manager.server.js @@ -77,12 +77,12 @@ function create_sse_manager({ max_clients = 1_000, max_connections_per_client = }, /** @param {ConnectionCallback} cb */ - on_connect(cb) { + on_connected(cb) { on_connected_callbacks.add(cb); }, /** @param {ConnectionCallback} cb */ - on_disconnect(cb) { + on_disconnected(cb) { on_disconnected_callbacks.add(cb); }, diff --git a/examples/sveltekit-sse/src/routes/sse/+server.js b/examples/sveltekit-sse/src/routes/sse/+server.js index ba0e56f..18a783a 100644 --- a/examples/sveltekit-sse/src/routes/sse/+server.js +++ b/examples/sveltekit-sse/src/routes/sse/+server.js @@ -1,11 +1,9 @@ import sse from '$lib/sse-manager.server.js'; -sse.on_connect((client_id, controllers) => { +sse.on_connected((client_id, controllers) => { // Send a list of all currently connected users to the user const clients = Array.from(sse.get_clients().keys()); - console.log(clients); - sse.emit_to_all({ event: 'client:list', data: JSON.stringify({ clients }) @@ -14,12 +12,14 @@ sse.on_connect((client_id, controllers) => { // If the user has closed all connected tabs // send a message to all other users -sse.on_disconnect((client_id, controllers) => { - if (controllers.size > 0) return; - - const message = { event: 'client:disconnected', data: JSON.stringify({ client_id }) }; +sse.on_disconnected((client_id, controllers) => { + // Send a list of all currently connected users to the user + const clients = Array.from(sse.get_clients().keys()); - sse.emit_to_all(message); + sse.emit_to_all({ + event: 'client:list', + data: JSON.stringify({ clients }) + }); }); /** @type {import('./$types').RequestHandler} */ From f289bc6f0f10a7448d6d892010ef5c809916f9d4 Mon Sep 17 00:00:00 2001 From: Karim Jordan Date: Tue, 18 Apr 2023 23:13:01 +0100 Subject: [PATCH 11/23] send messages and improve layout --- .../sveltekit-sse/src/routes/+page.server.js | 14 ++++++----- .../sveltekit-sse/src/routes/+page.svelte | 23 ++++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/examples/sveltekit-sse/src/routes/+page.server.js b/examples/sveltekit-sse/src/routes/+page.server.js index 0c04240..3592a97 100644 --- a/examples/sveltekit-sse/src/routes/+page.server.js +++ b/examples/sveltekit-sse/src/routes/+page.server.js @@ -5,15 +5,17 @@ export const actions = { async emit_to_all(event) { const data = await event.request.formData(); - const message = JSON.stringify({ text: data.get('text') }); - - sse.emit_to_all({ event: 'message', data: message }); + sse.emit_to_all({ + event: 'client:message', + data: JSON.stringify({ text: data.get('text') }) + }); }, async emit_to(event) { const data = await event.request.formData(); - const message = JSON.stringify({ text: data.get('text') }); - - sse.emit_to(data.get('client_id'), { event: 'message', data: message }); + sse.emit_to(data.get('client_id'), { + event: 'client:message', + data: JSON.stringify({ text: data.get('text') }) + }); } }; diff --git a/examples/sveltekit-sse/src/routes/+page.svelte b/examples/sveltekit-sse/src/routes/+page.svelte index e7d35a3..12ccf9c 100644 --- a/examples/sveltekit-sse/src/routes/+page.svelte +++ b/examples/sveltekit-sse/src/routes/+page.svelte @@ -18,6 +18,14 @@ +

Messages

+ +
    + {#each $sse.messages as message (message)} +
  1. {message.text}
  2. + {/each} +
+

Connected clients

    @@ -38,27 +46,26 @@ {/each}
- -
    - {#each $sse.messages as message (message)} -
  1. {message.text}
  2. - {/each} -