Skip to content

Commit 570a6df

Browse files
committed
setup some structure
1 parent 29bf5d8 commit 570a6df

18 files changed

+4685
-706
lines changed

frameworks/svelte/build.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const e = require('esbuild');
2+
const s = require('esbuild-svelte');
3+
4+
e.context({
5+
bundle: true,
6+
entryPoints: ['src/index.ts'],
7+
plugins: [s()],
8+
outdir: 'dist',
9+
platform: 'browser',
10+
format: 'esm',
11+
}).then(p => p.watch());

frameworks/svelte/index.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Document</title>
8+
<script type="module" src="dist/index.js"></script>
9+
</head>
10+
<body></body>
11+
</html>

frameworks/svelte/src/App.svelte

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
import { useHook as use } from './compat';
3+
import { useState } from 'react';
4+
import Button from './Button.svelte';
5+
6+
const result = use(() => useState(0));
7+
</script>
8+
9+
<Button on:click={console.log} f="f">Yo does this work</Button>
10+
{#if $result}
11+
{@const [count, setCount] = $result}
12+
<button on:click={() => setCount(c => c + 1)}>{count}</button>
13+
{/if}

frameworks/svelte/src/Button.svelte

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<script>
2+
import { onMount, createEventDispatcher, onDestroy } from 'svelte';
3+
import { Button as B } from './Button';
4+
import React from 'react';
5+
import ReactDOM from 'react-dom/client';
6+
7+
const dispatch = createEventDispatcher();
8+
9+
let ref;
10+
let root;
11+
12+
onMount(() => {
13+
console.log(props);
14+
const { $$slots, $$scope, ...p } = props;
15+
const props = new Proxy(p, {
16+
get(target, prop) {
17+
if (!(prop in target) && /^on[A-Z]/.test(prop)) {
18+
return e => {
19+
dispatch(prop.slice(2).toLowerCase(), e);
20+
};
21+
}
22+
},
23+
});
24+
root = ReactDOM.createRoot(ref).render(React.createElement(B, props));
25+
});
26+
27+
onDestroy(() => {
28+
root?.unmount();
29+
});
30+
</script>
31+
32+
<div style="display: contents" bind:this={ref} />

frameworks/svelte/src/Button.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import React from 'react';
2+
3+
export function Button(props) {
4+
return <button {...props} />;
5+
}

frameworks/svelte/src/compat.ts

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { render } from 'react-nil';
2+
import React from 'react';
3+
import { writable, get, readable, readonly } from 'svelte/store';
4+
5+
export function removeEvents(props) {
6+
return Object.fromEntries(
7+
Object.entries(props ?? {}).filter(([prop]) => !/^on[A-Z]/.test(prop))
8+
);
9+
}
10+
11+
function getEvents(props) {
12+
const events = Object.entries(props)
13+
.filter(([prop]) => /^on[A-Z]/.test(prop))
14+
.map(([event, handler]) => [event.slice(2).toLowerCase(), ev(handler)]);
15+
16+
return events;
17+
}
18+
19+
function ev(fn) {
20+
if (!fn) return fn;
21+
22+
return e => {
23+
e.nativeEvent = e;
24+
return fn(e);
25+
};
26+
}
27+
28+
export function setupEvents(node, obj) {
29+
const events = getEvents(obj);
30+
31+
for (const [name, handler] of events) {
32+
node.addEventListener(name, handler);
33+
}
34+
35+
return {
36+
destroy() {
37+
for (const [name, handler] of events) {
38+
node.removeEventListener(name, handler);
39+
}
40+
},
41+
};
42+
}
43+
44+
function createReactApp(hook, args, store) {
45+
return function ReactApp() {
46+
// const [statefulArgs, setStatefulArgs] = React.useState(_ => get(args));
47+
const _state = hook(...(get(args) as any));
48+
49+
console.log('doing');
50+
React.useEffect(() => {
51+
store.set(_state);
52+
}, [_state]);
53+
54+
// React.useEffect(() => {
55+
// const unsub = args.subscribe(setStatefulArgs);
56+
57+
// return () => unsub();
58+
// }, []);
59+
60+
store.set(_state);
61+
};
62+
}
63+
64+
export function useHook(hook, args = [], ctxs = []) {
65+
let store = writable(null);
66+
let ReactApp = createReactApp(
67+
hook,
68+
(args as any).subscribe ? args : readable(args),
69+
store
70+
);
71+
72+
console.log('starting');
73+
render(
74+
(ctxs as any).reduceRight((acc, [Comp, props = {}]) => {
75+
return React.createElement(Comp, props, acc);
76+
}, React.createElement(ReactApp as any))
77+
);
78+
console.log('end');
79+
80+
return readonly(store);
81+
}

frameworks/svelte/src/index.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import App from './App.svelte';
2+
3+
const app = new App({
4+
target: document.body,
5+
props: {},
6+
});
7+
8+
export default app;

0 commit comments

Comments
 (0)