custom element for embedding Bluesky posts and feeds
mary-ext.github.io/bluesky-embed
typescript
npm
bluesky
atcute
1import * as path from 'node:path';
2
3import { compile as compileSvelte } from 'svelte/compiler';
4import { type Plugin, createFilter, defineConfig } from 'vite';
5
6import preact from '@preact/preset-vite';
7import dts from 'vite-plugin-dts';
8
9export default defineConfig({
10 base: './',
11 build: {
12 outDir: 'dist/',
13 target: 'esnext',
14 minify: false,
15 cssMinify: false,
16 cssCodeSplit: true,
17 lib: {
18 entry: {
19 core: 'lib/core.ts',
20 wc: 'lib/wc.ts',
21 },
22 formats: ['es'],
23 },
24 rollupOptions: {
25 external: ['@atcute/client', '@atcute/bluesky-richtext-parser'],
26 },
27 },
28 esbuild: {
29 target: 'esnext',
30 },
31 plugins: [
32 svelte(),
33 preact(),
34 dts({
35 rollupTypes: true,
36 tsconfigPath: 'tsconfig.build.json',
37 beforeWriteFile(filePath, content) {
38 if (filePath.endsWith('/core.d.ts')) {
39 // Make sure the relevant types are present
40 return { content: `import '@atcute/bluesky/lexicons';\n${content}` };
41 }
42 },
43 }),
44 ],
45});
46
47function svelte(): Plugin {
48 const filter = createFilter('**/*.svelte');
49 const stylesheets = new Map<string, string>();
50
51 return {
52 name: 'svelte',
53 resolveId(id) {
54 return stylesheets.has(id) ? id : null;
55 },
56 load(id) {
57 const css = stylesheets.get(id);
58 if (css !== undefined) {
59 this.addWatchFile(id.slice(0, -4));
60 return { code: css };
61 }
62
63 return null;
64 },
65 transform(source, id) {
66 if (!filter(id)) {
67 return null;
68 }
69
70 const result = compileSvelte(source, {
71 generate: 'server',
72 css: 'external',
73 cssHash({ hash, filename }) {
74 const prefix = `github:mary-ext/bluesky-profile-card-embed/`;
75 return `s-` + hash(prefix + path.relative(__dirname, filename));
76 },
77 runes: true,
78 filename: id,
79 });
80
81 {
82 const { js, css, warnings } = result;
83
84 let jsCode = js.code;
85
86 if (css) {
87 const cssId = `${id}.css`;
88 jsCode = jsCode + `\nimport ${JSON.stringify(cssId)};\n`;
89 stylesheets.set(cssId, css.code);
90 }
91
92 for (const warn of warnings) {
93 if (warn.code === 'state_referenced_locally') {
94 continue;
95 }
96 this.warn(warn);
97 }
98
99 return { code: jsCode };
100 }
101 },
102 };
103}