diff --git a/.gitignore b/.gitignore index 605d6be6..bbc4a31f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ pnpm-debug.log* .eslint/.eslintcache public/upload/* src/graphql/introspec.gen.ts +stats.html diff --git a/.lintstagedrc b/.lintstagedrc index f6d24a5e..6de8a64b 100644 --- a/.lintstagedrc +++ b/.lintstagedrc @@ -2,5 +2,5 @@ "*.{js,ts,tsx,json,scss,css,html}": "prettier --write", "package.json": "sort-package-json", "*.{scss,css}": "stylelint", - "*.{ts,tsx,js}": "eslint --fix", + "*.{ts,tsx,js}": "eslint --fix" } diff --git a/astro.config.ts b/astro.config.ts index fb57d0b1..472928ed 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -1,15 +1,10 @@ import { defineConfig, AstroUserConfig } from 'astro/config' import vercel from '@astrojs/vercel/serverless' -// import node from '@astrojs/node' import solidJs from '@astrojs/solid-js' -import mdx from '@astrojs/mdx' -// import partytown from '@astrojs/partytown' -import { markdownOptions as markdown } from './mdx.config' -// import sitemap from '@astrojs/sitemap' import type { CSSOptions } from 'vite' import defaultGenerateScopedName from 'postcss-modules/build/generateScopedName' import { isDev } from './src/utils/config' -import { fileURLToPath, URL } from 'url' +import { visualizer } from 'rollup-plugin-visualizer' const PATH_PREFIX = '/src/' @@ -37,35 +32,51 @@ const css: CSSOptions = { const astroConfig: AstroUserConfig = { site: 'https://new.discours.io', - // Enable Solid to support Solid JSX components. - // experimental: { integrations: true }, - integrations: [solidJs(), mdx()], - // sitemap({ - /* customPages: [ - '', - '/feed', - '/search', - 'topics', - 'authors' - ] - })],*/ - //, partytown({})], - markdown, + integrations: [solidJs()], output: 'server', adapter: vercel(), vite: { build: { - chunkSizeWarningLimit: 777, rollupOptions: { + plugins: [visualizer()], + output: { + // eslint-disable-next-line sonarjs/cognitive-complexity + manualChunks(id) { + if (id.includes('node_modules')) { + let chunkid = 'vendor' + if (id.includes('solid')) { + chunkid = 'solid' + } + if (id.includes('acorn')) { + chunkid = 'acorn' + } + if (id.includes('simple-peer')) { + chunkid = 'simple-peer' + } + if (id.includes('prosemirror')) { + chunkid = 'prosemirror' + } + if (id.includes('markdown') || id.includes('mdurl')) { + chunkid = 'markdown' + } + if (id.includes('swiper')) { + chunkid = 'swiper' + } + if ( + id.includes('yjs') || + id.includes('y-prosemirror') || + id.includes('y-protocols') || + id.includes('y-webrtc') + ) { + chunkid = 'yjs' + } + return chunkid + } + } + }, external: ['@aws-sdk/clients/s3'] } }, - resolve: { - alias: { - './runtimeConfig': './runtimeConfig.browser', - '@': fileURLToPath(new URL('src', import.meta.url)) - } - }, css } } diff --git a/mdx.config.ts b/mdx.config.ts deleted file mode 100644 index a6a87346..00000000 --- a/mdx.config.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { AstroUserConfig } from 'astro' -import type { RehypePlugin } from '@astrojs/markdown-remark' -import { selectAll } from 'hast-util-select' -import rehypeToc from '@jsdevtools/rehype-toc' -import rehypeAutolinkHeadings from 'rehype-autolink-headings' -import rehypeSlug from 'rehype-slug' -import remarkCodeTitles from 'remark-code-titles' - -const write = - (cl) => - ({ properties }) => { - properties.className = properties.className ? properties.className + ' ' + cl : cl - } - -const adder = ([selector, className]) => { - const writer = write(className) - return (node) => selectAll(selector, node).forEach((el) => writer(el as any)) -} - -const addClasses = (additions) => { - const adders = Object.entries(additions).map((entry) => adder(entry)) - return (node) => adders.forEach((a) => a(node)) -} - -export const markdownOptions: AstroUserConfig['markdown'] = { - remarkPlugins: [remarkCodeTitles], - rehypePlugins: [ - rehypeSlug, - [rehypeToc as RehypePlugin, { headings: ['h1', 'h2', 'h3'] }], - [rehypeAutolinkHeadings, { behavior: 'prepend' }], - [addClasses, { 'h1,h2,h3': 'title' }] - ], - extendDefaultPlugins: true -} diff --git a/package.json b/package.json index 269e4cde..07e2d198 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ }, "dependencies": { "@aws-sdk/client-s3": "^3.178.0", - "@jsdevtools/rehype-toc": "^3.0.2", "@nanostores/persistent": "^0.7.0", "@nanostores/router": "^0.7.0", "@nanostores/solid": "^0.3.0", @@ -37,19 +36,18 @@ "loglevel": "^1.8.0", "loglevel-plugin-prefix": "^0.8.4", "mailgun.js": "^8.0.1", + "markdown-it": "^13.0.1", + "markdown-it-container": "^3.0.0", + "markdown-it-implicit-figures": "^0.10.0", + "markdown-it-mark": "^3.0.1", + "markdown-it-replace-link": "^1.1.0", "nanostores": "^0.7.0", - "postcss-modules": "^5.0.0", - "rehype-autolink-headings": "^6.1.1", - "rehype-slug": "^5.0.1", - "remark-code-titles": "^0.1.2" + "postcss-modules": "^5.0.0" }, "devDependencies": { - "@astrojs/markdown-remark": "1.1.2", - "@astrojs/mdx": "^0.11.1", - "@astrojs/node": "^1.0.1", - "@astrojs/partytown": "^1.0.0", + "@astrojs/language-server": "^0.27.0", "@astrojs/solid-js": "^1.1.0", - "@astrojs/vercel": "^2.0.0", + "@astrojs/vercel": "^2.1.0", "@babel/core": "^7.18.13", "@graphql-codegen/cli": "^2.12.1", "@graphql-codegen/typescript": "^2.7.3", @@ -114,7 +112,12 @@ "prosemirror-schema-list": "^1.2.2", "prosemirror-state": "^1.4.1", "prosemirror-view": "^1.28.1", + "rehype-autolink-headings": "^6.1.1", + "rehype-slug": "^5.0.1", + "rehype-toc": "^3.0.2", + "remark-code-titles": "^0.1.2", "rollup": "~2.79.1", + "rollup-plugin-visualizer": "^5.8.2", "sass": "^1.55.0", "solid-devtools": "^0.16.2", "solid-js": "^1.5.6", @@ -122,7 +125,7 @@ "solid-jsx": "^0.9.1", "solid-social": "^0.9.0", "solid-utils": "^0.8.1", - "sort-package-json": "^1.57.0", + "sort-package-json": "^2.0.0", "stylelint": "^14.12.1", "stylelint-config-css-modules": "^4.1.0", "stylelint-config-prettier-scss": "^0.0.1", diff --git a/src/components/Article/Comment.tsx b/src/components/Article/Comment.tsx index 4ad74a85..102cba7c 100644 --- a/src/components/Article/Comment.tsx +++ b/src/components/Article/Comment.tsx @@ -4,11 +4,10 @@ import { AuthorCard } from '../Author/Card' import { Show } from 'solid-js/web' import { clsx } from 'clsx' import type { Author, Reaction as Point } from '../../graphql/types.gen' -import { createMemo, createSignal, onMount } from 'solid-js' +import { createMemo } from 'solid-js' import { t } from '../../utils/intl' // import { createReaction, updateReaction, deleteReaction } from '../../stores/zine/reactions' -import { renderMarkdown } from '@astrojs/markdown-remark' -import { markdownOptions } from '../../../mdx.config' +import MD from './MD' import { deleteReaction } from '../../stores/zine/reactions' export default (props: { @@ -18,17 +17,7 @@ export default (props: { compact?: boolean }) => { const comment = createMemo(() => props.comment) - const [body, setBody] = createSignal('') - onMount(() => { - const b: string = props.comment?.body - if (b?.toString().startsWith('<')) { - setBody(b) - } else { - renderMarkdown(b, markdownOptions) - .then(({ code }) => setBody(code)) - .catch(console.error) - } - }) + const body = createMemo(() => comment().body.toString().trim()) const remove = () => { if (comment()?.id) { console.log('[comment] removing', comment().id) @@ -71,7 +60,7 @@ export default (props: {
-
+
diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index 094d957e..a499adc4 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -3,14 +3,13 @@ import './Full.scss' import { Icon } from '../Nav/Icon' import ArticleComment from './Comment' import { AuthorCard } from '../Author/Card' -import { createEffect, createMemo, createSignal, For, onMount, Show } from 'solid-js' +import { createMemo, For, onMount, Show } from 'solid-js' import type { Author, Reaction, Shout } from '../../graphql/types.gen' import { t } from '../../utils/intl' import { showModal } from '../../stores/ui' import { useAuthStore } from '../../stores/auth' import { incrementView } from '../../stores/zine/articles' -import { renderMarkdown } from '@astrojs/markdown-remark' -import { markdownOptions } from '../../../mdx.config' +import MD from './MD' const MAX_COMMENT_LEVEL = 6 @@ -38,24 +37,9 @@ const formatDate = (date: Date) => { } export const FullArticle = (props: ArticleProps) => { - const [body, setBody] = createSignal(props.article.body?.startsWith('<') ? props.article.body : '') - + const body = createMemo(() => props.article.body.toString().trim()) const { session } = useAuthStore() - createEffect(() => { - if (body() || !props.article.body) { - return - } - - if (props.article.body.startsWith('<')) { - setBody(props.article.body) - } else { - renderMarkdown(props.article.body, markdownOptions) - .then(({ code }) => setBody(code)) - .catch(console.error) - } - }) - onMount(() => { incrementView({ articleSlug: props.article.slug }) }) @@ -110,7 +94,7 @@ export const FullArticle = (props: ArticleProps) => {
-
+
diff --git a/src/components/Article/MD.tsx b/src/components/Article/MD.tsx new file mode 100644 index 00000000..4dd6cd9c --- /dev/null +++ b/src/components/Article/MD.tsx @@ -0,0 +1,24 @@ +import MD from 'markdown-it' +import mdfig from 'markdown-it-implicit-figures' +import mdmark from 'markdown-it-mark' +import mdcustom from 'markdown-it-container' +import mdlinks from 'markdown-it-replace-link' +import { createMemo } from 'solid-js' + +const mit = MD({ + html: true, + linkify: true, + typographer: true +}) +mit.use(mdmark) +mit.use(mdcustom) +mit.use(mdfig, { + dataType: false, //
+ figcaption: true //
alternative text
+}) +mit.use(mdlinks) + +export default (props: { body: string }) => { + const body = createMemo(() => (props.body.startsWith('<') ? props.body : mit.render(props.body))) + return
+} diff --git a/src/components/Editor/Editor.scss b/src/components/Editor/Editor.scss index 701fa99d..a8bdd9ae 100644 --- a/src/components/Editor/Editor.scss +++ b/src/components/Editor/Editor.scss @@ -1,3 +1,6 @@ +@import './Button'; +@import './Sidebar'; + .editor { flex: 1; padding-top: 1em; diff --git a/src/components/Editor/Error.tsx b/src/components/Editor/Error.tsx index f0353d96..c6d002d1 100644 --- a/src/components/Editor/Error.tsx +++ b/src/components/Editor/Error.tsx @@ -1,6 +1,5 @@ -import { Switch, Match } from 'solid-js' -import { useState } from './prosemirror/context' -import './Button.scss' +import { Switch, Match, createMemo } from 'solid-js' +import { ErrorObject, useState } from './store' const InvalidState = (props: { title: string }) => { const [store, ctrl] = useState() @@ -16,7 +15,7 @@ const InvalidState = (props: { title: string }) => { you can copy important notes from below, clean the state and paste it again.

-          {JSON.stringify(store.error?.props)}
+          {JSON.stringify(store.error)}