diff --git a/Dockerfile b/Dockerfile index 442987d0..afbbfb51 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,7 +47,6 @@ WORKDIR /remixapp COPY --from=production-deps /remixapp/node_modules /remixapp/node_modules COPY --from=build /remixapp/build /remixapp/build -COPY --from=build /remixapp/data /remixapp/data COPY --from=build /remixapp/server.js /remixapp/server.js COPY --from=build /remixapp/package.json /remixapp/package.json COPY --from=build /remixapp/start.sh /remixapp/start.sh diff --git a/app/lib/conf.server.ts b/app/lib/conf2022.server.ts similarity index 74% rename from app/lib/conf.server.ts rename to app/lib/conf2022.server.ts index ce02840c..43de8cc5 100644 --- a/app/lib/conf.server.ts +++ b/app/lib/conf2022.server.ts @@ -1,5 +1,3 @@ -import fsp from "fs/promises"; -import path from "path"; import invariant from "tiny-invariant"; import { processMarkdown } from "~/lib/md.server"; @@ -27,6 +25,11 @@ import { sluggify, } from "./conf"; +import speakersYamlFileContents from "../../data/conf/2022/speakers.yaml?raw"; +import sponsorsYamlFileContents from "../../data/conf/2022/sponsors.yaml?raw"; +import talksYamlFileContents from "../../data/conf/2022/talks.yaml?raw"; +import scheduleYamlFileContents from "../../data/conf/2022/schedule.yaml?raw"; + let cache = new LRUCache< string, Array | Array | Array | Array @@ -38,30 +41,13 @@ let cache = new LRUCache< }, }); -const DATA_DIR = path.join(process.cwd(), "data"); -const CONF_ROOT_DIR = path.join(DATA_DIR, "conf"); - -function getConfPaths(year: ConfYear) { - let confDir = path.join(CONF_ROOT_DIR, String(year)); - return { - speakersFile: path.join(confDir, "speakers.yaml"), - sponsorsFile: path.join(confDir, "sponsors.yaml"), - talksFile: path.join(confDir, "talks.yaml"), - scheduleFile: path.join(confDir, "schedule.yaml"), - }; -} - -type ConfYear = 2022 | 2023; - -export async function getSpeakers(year: ConfYear) { - let cached = cache.get(`speakers-${year}`); +export async function getSpeakers() { + let cached = cache.get("speakers"); if (isSpeakerArray(cached)) { return cached; } - let { speakersFile: SPEAKERS_FILE } = getConfPaths(year); - let speakersFileContents = await fsp.readFile(SPEAKERS_FILE, "utf8"); - let speakersRaw = yaml.parse(speakersFileContents); + let speakersRaw = yaml.parse(speakersYamlFileContents); let speakers: Array = []; for (let speakerRaw of speakersRaw) { let { html: bioHTML } = await processMarkdown(speakerRaw.bio); @@ -86,15 +72,13 @@ export async function getSpeakers(year: ConfYear) { return speakers; } -export async function getSponsors(year: ConfYear) { - let cached = cache.get(`sponsors-${year}`); +export async function getSponsors() { + let cached = cache.get("sponsors"); if (isSponsorArray(cached)) { return cached; } - let { sponsorsFile: SPONSORS_FILE } = getConfPaths(year); - let sponsorsFileContents = await fsp.readFile(SPONSORS_FILE, "utf8"); - let sponsorsRaw = yaml.parse(sponsorsFileContents); + let sponsorsRaw = yaml.parse(sponsorsYamlFileContents); let sponsors: Array = []; for (let sponsorRaw of sponsorsRaw) { invariant( @@ -110,15 +94,13 @@ export async function getSponsors(year: ConfYear) { return sponsors; } -export async function getTalks(year: ConfYear) { - let cached = cache.get(`talks-${year}`); +export async function getTalks() { + let cached = cache.get("talks"); if (isTalkArray(cached)) { return cached; } - let { talksFile: TALKS_FILE } = getConfPaths(year); - let talksFileContents = await fsp.readFile(TALKS_FILE, "utf8"); - let talksRaw = yaml.parse(talksFileContents); + let talksRaw = yaml.parse(talksYamlFileContents); let talks: Array = []; for (let talkRaw of talksRaw) { invariant( @@ -138,18 +120,16 @@ export async function getTalks(year: ConfYear) { return talks; } -export async function getSchedule(year: ConfYear) { - let cached = cache.get(`schedule-${year}`); +export async function getSchedule() { + let cached = cache.get("schedule"); if (isScheduleItemArray(cached)) { return cached; } - let { scheduleFile: SCHEDULE_FILE } = getConfPaths(year); - let allTalks = await getTalks(year); - let allSpeakers = await getSpeakers(year); + let allTalks = await getTalks(); + let allSpeakers = await getSpeakers(); - let schedulesFileContents = await fsp.readFile(SCHEDULE_FILE, "utf8"); - let scheduleItemsRaw = yaml.parse(schedulesFileContents); + let scheduleItemsRaw = yaml.parse(scheduleYamlFileContents); let scheduleItems: Array = []; for (let scheduleItemRaw of scheduleItemsRaw) { diff --git a/app/lib/conf2023.server.ts b/app/lib/conf2023.server.ts index 32e79526..54c453c4 100644 --- a/app/lib/conf2023.server.ts +++ b/app/lib/conf2023.server.ts @@ -1,10 +1,13 @@ import LRUCache from "lru-cache"; import { DateTime } from "luxon"; +import yaml from "yaml"; +import invariant from "tiny-invariant"; import { sluggify, validateSessionizeSessionData, validateSessionizeSpeakerData, } from "./conf2023"; +import sponsorsYamlFileContents from "../../data/conf/2023/sponsors.yaml?raw"; import type { Speaker, SpeakerSession, @@ -13,6 +16,8 @@ import type { SessionizeSpeakerData, SessionizeSessionData, } from "./conf2023"; +import type { Sponsor } from "./conf"; +import { isSponsor, isSponsorArray } from "./conf"; const CONF_TIME_ZONE = "America/Denver"; const NO_CACHE = @@ -20,13 +25,14 @@ const NO_CACHE = const SPEAKERS_CACHE_KEY = "speakers"; const SESSIONS_CACHE_KEY = "sessions"; const SCHEDULES_CACHE_KEY = "schedules"; +const SPONSORS_CACHE_KEY = "schedules"; const SESSIONIZE_ENDPOINT = "https://sessionize.com/api/v2/s8ds2hnu"; const SESSIONIZE_API_DETAILS_URL = "https://sessionize.com/app/organizer/schedule/api/endpoint/9617/7818"; let cache = new LRUCache< "speakers" | "sessions" | "schedules", - (Speaker | SpeakerSession | Schedule)[] + (Speaker | SpeakerSession | Schedule | Sponsor)[] >({ max: 250, maxSize: 1024 * 1024 * 12, // 12 mb @@ -495,3 +501,25 @@ async function fetchNaiveStaleWhileRevalidate( }); } } + +export async function getSponsors() { + let cached = cache.get(SPONSORS_CACHE_KEY); + if (isSponsorArray(cached)) { + return cached; + } + + let sponsorsRaw = yaml.parse(sponsorsYamlFileContents); + let sponsors: Array = []; + for (let sponsorRaw of sponsorsRaw) { + invariant( + isSponsor(sponsorRaw), + `Sponsor ${JSON.stringify( + sponsorRaw, + )} is not valid. Please check the sponsors file.`, + ); + sponsors.push(sponsorRaw); + } + cache.set(SPONSORS_CACHE_KEY, sponsors); + + return sponsors; +} diff --git a/app/routes/conf.2022._index.tsx b/app/routes/conf.2022._index.tsx index befd1511..3c83026b 100644 --- a/app/routes/conf.2022._index.tsx +++ b/app/routes/conf.2022._index.tsx @@ -7,7 +7,7 @@ import { OutlineButtonLink, primaryButtonLinkClass } from "~/ui/buttons"; import "~/styles/index.css"; import { Fragment } from "react"; import type { Sponsor, Speaker } from "~/lib/conf"; -import { getSpeakers, getSponsors } from "~/lib/conf.server"; +import { getSpeakers, getSponsors } from "~/lib/conf2022.server"; import { Link } from "~/ui/link"; import { CACHE_CONTROL } from "~/lib/http.server"; @@ -35,7 +35,7 @@ export const meta: MetaFunction = (args) => { }; export const loader = async ({ request }: LoaderFunctionArgs) => { - const speakersOrdered = await getSpeakers(2022); + const speakersOrdered = await getSpeakers(); const speakersShuffled = speakersOrdered // save a bit of data by not sending along the bio to the home page .map( @@ -47,7 +47,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { ) .sort(() => Math.random() - 0.5); - const allSponsors = await getSponsors(2022); + const allSponsors = await getSponsors(); const sponsors = { premier: allSponsors.find((s) => s.level === "premier"), gold: allSponsors diff --git a/app/routes/conf.2022._inner.schedule.may-25.tsx b/app/routes/conf.2022._inner.schedule.may-25.tsx index 2f2848f4..f7c77155 100644 --- a/app/routes/conf.2022._inner.schedule.may-25.tsx +++ b/app/routes/conf.2022._inner.schedule.may-25.tsx @@ -3,7 +3,7 @@ import { json } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; import type { MetaFunction } from "@remix-run/react"; import { metaV1 } from "@remix-run/v1-meta"; -import { getSchedule } from "~/lib/conf.server"; +import { getSchedule } from "~/lib/conf2022.server"; import { CACHE_CONTROL } from "~/lib/http.server"; import { sluggify } from "~/lib/conf"; @@ -17,7 +17,7 @@ export const meta: MetaFunction = (args) => { type LoaderData = { scheduleItems: Awaited> }; export const loader: LoaderFunction = async () => { - const scheduleItems = await getSchedule(2022); + const scheduleItems = await getSchedule(); return json( { scheduleItems }, { headers: { "Cache-Control": CACHE_CONTROL.DEFAULT } }, diff --git a/app/routes/conf.2022._inner.speakers.$speakerSlug.tsx b/app/routes/conf.2022._inner.speakers.$speakerSlug.tsx index 4f622d1e..3657aabd 100644 --- a/app/routes/conf.2022._inner.speakers.$speakerSlug.tsx +++ b/app/routes/conf.2022._inner.speakers.$speakerSlug.tsx @@ -9,7 +9,7 @@ import { import type { MetaFunction } from "@remix-run/react"; import { json } from "@remix-run/node"; import { metaV1 } from "@remix-run/v1-meta"; -import { getSpeakers, getTalks } from "~/lib/conf.server"; +import { getSpeakers, getTalks } from "~/lib/conf2022.server"; import "~/styles/conf-speaker.css"; import { sluggify } from "~/lib/conf"; import { CACHE_CONTROL } from "~/lib/http.server"; @@ -34,8 +34,8 @@ export const meta: MetaFunction = (args) => { export const loader = async ({ params }: LoaderFunctionArgs) => { const [allTalks, allSpeakers] = await Promise.all([ - getTalks(2022), - getSpeakers(2022), + getTalks(), + getSpeakers(), ]); const speaker = allSpeakers.find((s) => s.slug === params.speakerSlug); if (!speaker) throw new Response("Speaker not found", { status: 404 }); diff --git a/app/routes/conf.2022._inner.workshops.tsx b/app/routes/conf.2022._inner.workshops.tsx index f5245f86..5e0bee88 100644 --- a/app/routes/conf.2022._inner.workshops.tsx +++ b/app/routes/conf.2022._inner.workshops.tsx @@ -42,7 +42,7 @@ export default function Workshops() { href="https://twitter.com/kentcdodds" > Kent C. Dodds @@ -53,7 +53,7 @@ export default function Workshops() { href="https://twitter.com/ryanflorence" > Ryan Florence diff --git a/app/routes/conf.2023._index.tsx b/app/routes/conf.2023._index.tsx index a67d2efd..90d5d1e7 100644 --- a/app/routes/conf.2023._index.tsx +++ b/app/routes/conf.2023._index.tsx @@ -10,11 +10,10 @@ import { } from "~/ui/buttons"; import "~/styles/index.css"; import { Fragment } from "react"; -import { getSponsors } from "~/lib/conf.server"; import type { Sponsor, SponsorLevel } from "~/lib/conf"; import { Link } from "~/ui/link"; import { CACHE_CONTROL } from "~/lib/http.server"; -import { getSpeakers } from "~/lib/conf2023.server"; +import { getSpeakers, getSponsors } from "~/lib/conf2023.server"; import type { Speaker } from "~/lib/conf2023"; export const meta: MetaFunction = (args) => { @@ -50,7 +49,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { console.error(err); } - let allSponsors = await getSponsors(2023); + let allSponsors = await getSponsors(); let sponsors: Partial> = {}; for (let sponsor of allSponsors.sort(randomSort)) { let level = sponsor.level; @@ -149,7 +148,7 @@ function EarlySponsors() {

- +
diff --git a/data/conf/2023/schedule.yaml b/data/conf/2023/schedule.yaml deleted file mode 100644 index ff4e4bc1..00000000 --- a/data/conf/2023/schedule.yaml +++ /dev/null @@ -1,89 +0,0 @@ -- time: 7:30 AM - title: Breakfast & Registration 🍞 🥚 🥞 🍳 🍵 🥣 🥓 🍩 - content: - A delicious hot breakfast is hosted in the hotel next to the conference - room. If you didn't register the day before, now's the time to get your swag - bag and lanyard! - -- time: 9:00 AM - title: Opening Remarks - content: Ceora will get us oriented on important logistics for the conference. - speakers: - - Ceora Ford - -- time: 9:10 AM - talk: Keynote - -- time: 9:35 AM - talk: How To WebPageTest - -- time: 10:00 AM - talk: "Instantaneously Interactive: Remix as a Browser Framework" - -- time: 10:25 AM - talk: State Machines On The Edge - -- time: 10:50 AM - title: ☕ Morning Break - content: - These breaks are extra long to give you time to visit with other attendees! - Take advantage of that! - -- time: 11:15 AM - talk: Remixing Hydrogen - -- time: 11:40 AM - talk: Deno and Remix - -- time: 12:05 PM - talk: Remix 3D Blast - -- time: 12:10 PM - talk: "Web Vitals: The importance of measuring a user great web experience" - -- time: 12:15 PM - talk: Making slow responses seem fast with stale-while-revalidate - -- time: 12:20 PM - title: - Lunch 🥪 🌮 🥘 🍣 🥗 🍐 🌯 🥒 🍝 🌭 🥩 🍜 🦐 🥨 🥟 🍕 🥙 🍔 🍚 🍱 🍛 🍲 🍢 - content: - You'll get a pre-paid card and directions to various local restaurants. The - lunch break is extra long so you can take the opportunity to get to know - other attendees (and to give you time to get to and from a local restaurant - to enjoy). Take advantage of the time! But make it back for the afternoon of - talks. - -- time: 2:25 PM - talk: Building tech for social good with low-code tools - -- time: 2:30 PM - talk: Expanding Remix with Rust - -- time: 2:35 PM - talk: "Full Stack Fast: Data on the Edge" - -- time: 2:45 PM - talk: Remix your UI & UX to another level - -- time: 3:10 PM - talk: Magically create forms + actions with Remix Forms - -- time: 3:35 PM - talk: Incremental Remix - -- time: 4:00 PM - title: ☕ Afternoon Break - content: This is the last break of the day. Take some deep breaths! - -- time: 4:25 PM - talk: Outstanding Search Experiences with Remix and Algolia - -- time: 4:50 PM - talk: Switching to Remix at Neighbor - -- time: 5:15 PM - title: Closing Remarks - content: Ceora will help us wrap and thank you for coming! - speakers: - - Ceora Ford diff --git a/data/conf/2023/speakers.yaml b/data/conf/2023/speakers.yaml deleted file mode 100644 index 2f933175..00000000 --- a/data/conf/2023/speakers.yaml +++ /dev/null @@ -1,345 +0,0 @@ -- name: "Ryan Dahl" - linkText: "@ry" - link: "https://github.com/ry" - title: "CEO, Deno + Creator of Node.js" - imgSrc: "/conf-images/speakers/ryan.jpg" - bio: >- - In 2009, Ryan Dahl released [Node.js](https://nodejs.org/). Now, Ryan is the - CEO of [Deno](https://deno.com/), the company behind [the Deno - project](https://deno.land): A modern runtime for JavaScript and TypeScript. - [Deno's deploy product](https://deno.com/deploy) is pushing this runtime in - the future of modern web architecture via multi-regional deploys with an - outrageously fast runtime. - -- name: "Shaundai Person" - linkText: "@shaundai" - link: "https://twitter.com/shaundai" - title: "Senior Software Engineer, Netflix" - imgSrc: "/conf-images/speakers/shaundai.jpg" - bio: >- - Shaundai is a Senior Software Engineer (Netflix) and educator based in - Atlanta, GA, US. She is passionate about making programming interesting and - approachable for all, and does that through her work as a course instructor - ([tsforjs.com](https://www.tsforjs.com/)), co-lead for React Robins - ([reactrobins.com](https://www.reactrobins.com/)), and [technical - blogger](https://blog.shaundai.com/). - - - In her spare time, Shaundai loves to go hiking, jogging, and listen to - audiobooks. Find her on Twitter at - [@shaundai](https://twitter.com/shaundai). - -- name: "Anthony Frehner" - linkText: "@frehner_a" - link: "https://twitter.com/frehner_a" - title: "Senior Software Engineer at Shopify" - imgSrc: "/conf-images/speakers/anthony.jpg" - bio: >- - Anthony Frehner is a frontend web developer and architect. He likes to - contribute to open source when he has the time! Anthony is currently working - on [Hydrogen](https://hydrogen.shopify.dev/) 🙂 - - - Anthony's recently been providing feedback on a [WICG - proposal](https://github.com/WICG/app-history) for which he also spent some - time making a [polyfill](https://github.com/frehner/appHistory). He's a - core-team member of the [single-spa](https://single-spa.js.org) open source - library, he occasionally give conference talks–here's Anthony's talk at - [React Rally 2019](https://youtu.be/RgqSlRbbvwA)–and [write technical - articles](https://dev.to/frehner), and he proposed a new CSS unit called - [vhc](https://github.com/w3c/csswg-drafts/issues/4329) which eventually - turned into the [`dvh`, `lvh`, and - `svh`](https://dev.to/frehner/css-vh-dvh-lvh-svh-and-vw-units-27k4) (and - equivalent `*vw`) CSS units, which was [very - exciting](https://twitter.com/frehner_a/status/1405915191582380041) for him - personally! - -- name: "Michael Jackson" - linkText: "@mjackson" - link: "https://twitter.com/mjackson" - title: "Co-Founder & CEO, Remix" - imgSrc: "/m.jpg" - bio: >- - Michael Jackson is the CEO and co-creator/co-founder of - [Remix](https://remix.run). He is the co-author of [React - Router](https://reactrouter.com/) and a [prolific contributor to open - source](https://github.com/mjackson). He is the creator of - [unpkg.com](https://unpkg.com) and gets a kick out of discussing distributed - system design as much as he enjoys front-end architecture. Michael lives in - Carlsbad, CA with his wife, two boys, and two girls. - -- name: "Ceora Ford" - type: "emcee" - linkText: "@ceeoreo_" - link: "https://twitter.com/ceeoreo_" - title: "Developer Advocate, Apollo" - imgSrc: "/conf-images/speakers/ceora.jpg" - bio: >- - Ceora is a developer advocate based in Philadelphia. Her career thus far has - centered around creating educational content focused on making the tech - industry more accessible to everyone. She's been able to work with amazing - companies like [CodeSandbox](https://codesandbox.com), - [DigitalOcean](https://digitalocean.com), [egghead.io](https://egghead.io), - and [Apollo GraphQL](https://www.apollographql.com) and has recently joined - [the Stack Overflow Podcast](https://stackoverflow.blog/podcast) as a host. - Outside of tech, she spends way too much time watching anime, listening to - K-pop, and attempting to play the guitar. - -- name: "Sébastien Morel" - linkText: "@sebastienmorel" - link: "https://www.linkedin.com/in/sebastienmorel" - title: "Chief Technology Officer at Crystallize" - imgSrc: "/conf-images/speakers/sebastien.jpg" - bio: >- - Sébastien is a passionate and accomplished tech leader and problem-solver - with extensive experience in architecture, performance optimizations, - development, and system administration. CTO at Crystallize, a super-fast, - super modern, super sexy, and super-powerful Headless eCommerce"", he's in - charge (among other) of the Developer eXperience initiative. - - - Previously, he led and grew his former web agency for 18 years working on - more than 150 projects successfully and proudly implemented, deployed and - maintained. Agnostic of the web technology he's using, Sébastien is also an - open source maintainer active in the PHP/Symfony community. - -- name: "Arisa Fukuzaki" - linkText: "@arisa_dev" - link: "https://twitter.com/arisa_dev" - title: "DevRel Engineer at Storyblok" - imgSrc: "/conf-images/speakers/arisa.jpg" - bio: >- - Arisa is a DevRel Engineer at Storyblok & an organizer of a free tech skill - & knowledge-sharing community, Lilac. Her mission is to learn, speak, - connect and help. In her private time, she is a podcaster, an Aikido - fighter, and a GirlCode ambassador. - -- name: "Greg Brimble" - linkText: "@GregBrimble" - link: "https://twitter.com/GregBrimble" - title: "Systems Engineer at Cloudflare" - imgSrc: "/conf-images/speakers/greg.jpg" - bio: >- - Greg is a Systems Engineer at [Cloudflare](https://www.cloudflare.com/) - working on [Cloudflare Pages](https://pages.cloudflare.com/) in the Emerging - Technologies and Incubation department. Cloudflare Pages is a full-stack - developer platform and [they were very excited to add support for Remix at - the end of last - year](https://blog.cloudflare.com/remix-on-cloudflare-pages/). - - - Before Pages, Greg worked with Cloudflare's Speed Team where he learned to - appreciate the Network tab of DevTools. Greg has also contributed to the Web - Almanac and numerous open-source projects, and, most importantly, he has his - fingers crossed for enough snow to go [skiing after Remix - Conf](https://remix.run/conf/schedule/may-26)! ⛷ - -- name: "Nick Small" - linkText: "nickjs.com" - link: "https://nickjs.com" - title: "JavaScript Developer" - imgSrc: "/conf-images/speakers/nick.jpg" - bio: >- - Nick is a long-time dev of many disciplines: JavaScript, full-stack, native, - operating systems, game dev. He's motivated by improving people's lives by - finding really bad software in consequential places and making it better. - Nick's been an early employee at mission-driven companies like Shopify and - Devoted Health; empowered citizens and civil servants at US Digital Service, - Defense Digital Service, and the NATO mission in Afghanistan; and - volunteered on projects to strengthen democracy and build municipal Open - Data pipelines. - - - These days Nick lives in the mountains with his wife and kids, and he's - focused on tooling to let more people write more accessible software with - fewer bugs. Go Remix. Active hobbies include: constructing crosswords - (poorly), flying planes (successfully) (so far), building better houses - (fingers crossed). - -- name: "Scott Smerchek" - linkText: "@smerchek" - link: "https://twitter.com/smerchek" - title: "Software Engineer at UDisc" - imgSrc: "/conf-images/speakers/scott.jpg" - bio: >- - Scott's a software engineer with over a decade of experience building web - applications for healthcare enterprises from frontend, to APIs, and even - infrastructure. Now Scott works at UDisc, a quickly growing disc golf - company that is pushing the sport forward through technology. Scott's always - favored working in the backend, but Remix is helping him to enjoy working - across the full stack, once again. He's incredibly excited about the future - of building web applications with Remix and the ease of deploying to the - modern edge hosting providers. - -- name: "Erick Tamayo" - linkText: "@ericktamayo" - link: "https://twitter.com/ericktamayo" - title: "Senior Web Developer at Shopify" - imgSrc: "/conf-images/speakers/erick.jpg" - bio: >- - Erick Tamayo was born in the Dominican Republic. He currently lives in - Calgary Canada with his family. Erick's currently developing Metronome which - is a tool for Real User Monitoring (RUM) specifically for Remix. He's been - following Remix since 2020 and decided to join the community in 2021. Since - then he's loved everything about Remix and its community! - -- name: "Ben Wishovich" - linkText: "@iambenwis" - link: "https://twitter.com/iambenwis" - title: "Full Stack Web Dev" - imgSrc: "/conf-images/speakers/ben.jpg" - bio: >- - Ben is a full stack web developer and software quality engineer with - experience building high performance web applications. He's excited about - using Remix and Rust to expand the possibilities and performance of the web - app. When not coding, Ben might be found running around outside, cooking, or - reading sci-fi in the sunny SF Bay Area. - -- name: "Vic Vijayakumar" - linkText: "@VicVijayakumar" - link: "https://twitter.com/VicVijayakumar" - title: "Staff engineer at Eventbrite" - imgSrc: "/conf-images/speakers/vic.jpg" - bio: >- - Vic is a Staff Engineer @ Eventbrite and indie software maker from Raleigh, - North Carolina. He's a dad, runner, violinist, and is severely addicted to - acquiring new hobbies. He has run the tech side of North Carolina's - extremely popular Rare & Vintage Beer Festival for the last 10 years. - - - Vic was previously in the scientific communications space and a technical - cofounder of the Research Square platform, an inaugural recipient of the - Fast Company "Brands that Matter" list for accelerating research - communication during the pandemic. - - - In his spare time, you can find Vic building LEGO with his family or out at - the plant nursery adopting yet another plant. - -- name: "Daniel Weinmann" - linkText: "@danielweinmann" - link: "https://twitter.com/danielweinmann" - title: "Founder and CEO at Seasoned" - imgSrc: "/conf-images/speakers/daniel.jpg" - bio: >- - In order to bring his startups to life, Daniel had to go through a 9-year - journey to become the technical founder and CTO he needed in his teams. - However, his real passion has always been the non-technical way, and having - to spend his days coding took a toll on him. - - - When Daniel was finally able to come back to the business side, he had a - secret weapon: in his struggles to leave the technical life behind, he - gained a deep understanding of what it takes for a non-technical founder to - create successful startups. - - - Beyond his own journey, he's helped tons of founders build world-class - products over the last 20+ years. Along the way, he was CEO, CMO, and CTO of - many startups. Daniel has also founded a few successful ones himself, - including Mailee, which was sold to a Brazilian internet provider, and - Catarse, the biggest crowdfunding platform in Latin America. - -- name: "Sarah Dayan" - linkText: "@frontstuff_io" - link: "https://twitter.com/frontstuff_io" - title: "Staff Software Engineer at Algolia" - imgSrc: "/conf-images/speakers/sarah.jpg" - bio: >- - Sarah is a Staff Software Engineer from Paris, France who works on front-end - search experiences at Algolia. - - - She created the [Dinero.js](https://github.com/dinerojs/dinero.js) monetary - library and hosts the [Developer - Experience](https://developerexperience.buzzsprout.com/) podcast show. She's - passionate about building dynamic front-end experiences, and won't shut up - about TDD and utility-first CSS. She shares what she learns on [her - blog](https://frontstuff.io/) and at tech conferences around the world. - -- name: "Erik Rasmussen" - linkText: "@erikras" - link: "https://twitter.com/erikras" - title: "Software Engineer at Centered" - imgSrc: "/conf-images/speakers/erik.jpg" - bio: >- - Erik is an expat American living in Spain. He's the author of Redux Form and - Final Form, and is currently in love with TypeScript, XState, and Remix. His - day job is using those technologies to build Centered.app, a tool to combat - the Twitters' and Facebooks' attempts to steal your attention, and give it - back to you to be more productive in your work. - -- name: "Dennis Beatty" - linkText: "@dnsbty" - link: "https://twitter.com/dnsbty" - title: "Senior Software Engineer at Neighbor" - imgSrc: "/conf-images/speakers/dennis.jpg" - bio: >- - Dennis works as a senior software engineer at Neighbor, a marketplace for - self-storage, where he led the switch to Remix. While Dennis works across - the entire tech stack, he's especially comfortable with systems architecture - and seeing how pieces fit together. He's contributed to [open - source](https://github.com/dnsbty) software in various ways (mostly within - the Elixir ecosystem) and has enjoyed sharing some of his learning on [his - blog](https://dennisbeatty.com) and [his Youtube - channel](https://www.youtube.com/channel/UC9l_1J8y_au9Nlgrfz0rduw). Outside - of programming Dennis loves spending time with his wife and his daughter who - was born this past year, and he also skis, explores Utah's national forests, - and shoots photos of the stars. - -- name: "Jon Jensen" - linkText: "@jenseng" - link: "https://twitter.com/jenseng" - title: "Senior Software Engineer at Netflix" - imgSrc: "/conf-images/speakers/jon.jpg" - bio: >- - Jon is a Senior Software Engineer (Netflix) working to improve the developer - experience for other UI engineers. Previously he worked at Amazon and - Instructure working on various things software-y. In his spare time, he's - usually in the mountains, playing Minecraft with his kids, or following the - Red Food Truck around SLC. - -- name: "Henri Helvetica" - linkText: "@HenriHelvetica" - link: "https://twitter.com/HenriHelvetica" - title: "Software Engineer at Catchpoint Systems" - imgSrc: "/conf-images/speakers/henri.jpg" - bio: >- - Henri is a developer who has turned his interests to a passionate mix of - site performance engineering and pinches of user experience, which led to - his joining Catchpoint Systems on the WebPageTest Team. When not reading the - deluge of daily research docs and case studies, or profiling sites in his - favourite tools, Henri can be found contributing back to the community: - Toronto Web Performance Group meetup + Jamstack Toronto organizer, curating - conference content or volunteering his time for lunch and learns at various - bootcamps. Otherwise, Henri is focusing on running the fastest 5k possible - (surprise surprise), encouraging a healthy lifestyle via `#devsWhoRun`. - -- name: "Emily Kauffman" - linkText: "@intrepid_em" - link: "https://twitter.com/intrepid_em" - title: "Lead Software Engineer at Harvie" - imgSrc: "/conf-images/speakers/emily.png" - bio: >- - Emily is a Lead Software Engineer based out of Pittsburgh, PA. She's a - lifelong learner, adjunct professor, and IoT enthusiast. Emily has a tech - background in healthcare, robotics, and more recently, bringing local food - to the masses at [Harvie](https://www.harvie.farm). In her spare time, you - can find Emily tinkering with her homemade conversion van, scuba diving, or - trying her hand at landscape photography. - -- name: "Aaron K Saunders" - linkText: "@aaronksaunders" - link: "https://twitter.com/aaronksaunders" - title: "Founder & CEO of Clearly Innovative" - imgSrc: "/conf-images/speakers/aaron.jpg" - bio: >- - Aaron is an Information Technology Strategist, Thought Leader, and Diversity - and Inclusion Trailblazer - Founder & CEO of Clearly Innovative. He believes - technology and in his case coding is an enabler and an equalizer. Aaron has - focused a large part of his career training and developing individuals who - want to get into tech but cannot find the opening; through the - apprenticeship program he ran at Clearly Innovative, teaching web and mobile - development at Howard University, and the free technical videos on his - Youtube Channel he just want to help others get a seat at the table of tech - and innovation. diff --git a/data/conf/2023/talks.yaml b/data/conf/2023/talks.yaml deleted file mode 100644 index 0c14b168..00000000 --- a/data/conf/2023/talks.yaml +++ /dev/null @@ -1,320 +0,0 @@ -- title: Keynote - time: 9:10 AM - type: regular - description: Michael will kick the inaugural Remix Conference off! - speakers: - - Michael Jackson - -- title: "Instantaneously Interactive: Remix as a Browser Framework" - time: 10:00 AM - type: regular - description: >- - Your Remix app is so performant that–even without a solid internet - connection–navigation on your site seems to happen almost instantaneously. - Whether rendered on the client side or server side, pages load data quickly - and all the information you users are interested in is on the screen without - the wait. But why? - - - In this talk, we discuss the optimizations in Remix for data fetching and - rendering apps in the browser that enhance both the user experience and - developer experience. - - speakers: - - Shaundai Person - -- title: "State Machines On The Edge" - time: 10:25 AM - type: regular - description: >- - Modeling business logic with state machines has numerous benefits, from - eliminating bugs caused by impossible states to visualizing the logic to - communicate with non-technical shareholders to simply communicating user - flow between technical colleagues. In this talk, I'm going to demonstrate, - via live coding, how to combine the strengths of Remix and XState to create - a checkout flow entirely on the backend. No. JavaScript. Required. - speakers: - - Erik Rasmussen - -- title: Remixing Hydrogen - time: 11:15 AM - type: regular - description: >- - Let's talk about some of the headaches of building headless Shopify - e-commerce stores, and how Hydrogen-UI + Remix make it better. Pre-built - Shopify components? Check. GraphQL auto-completion? Oh yeah. Speedy - websites? Blazing fast. - speakers: - - Anthony Frehner - -- title: Deno and Remix - time: 11:40 AM - type: regular - description: >- - In this talk Ryan will give an overview of Deno, a modern JavaScript - runtime, and Deno Deploy, a serverless at edge JavaScript hosting service. - He'll give a peak behind the sceenes at the technology powering Deno Deploy, - and of course demo how to deploy a Remix app on it. - speakers: - - Ryan Dahl - -- title: Remix 3D Blast - time: 12:05 PM - type: lightning - description: >- - Whether you want to progressively enhance a traditional website or build an - immersive 3D experience, Remix gives us a powerful and fun framework to - create with WebGL and three.js. After deploying a 3D Remix experience to - production, I've found that all the patterns that Remix provides are just as - valuable even when we're not rendering to the DOM. In this talk, I'll show - off some zany 3D antics to explain how Remix and react-three-fiber can work - together to help you build fantastic experiences for your users. - - - We'll focus on: getting react-three-fiber set up in a Remix app; using - nested routes and layouts to render a scene; moving scene state to the - server with loaders and actions; streaming dynamic 3D resources to the - client using resource routes; and finally, transitions and optimistic UI... - in 3D! 💿 Rachel the Remix Disc will offer some nifty optimization tips - along the way. - - - It'll be a GL-and-web-fundamentals-fuelled blast! - speakers: - - Nick Small - -- title: "Web Vitals: The importance of measuring a user great web experience" - time: 12:10 PM - type: lightning - description: >- - Nowadays, building a working web application is much more than deploying it - to production. The impact on the way your app is delivered to your end-users - is also important. - - - Making your app experience better translates into more engagement, - conversions, and revenue. That's why it is also vital (pun intended) to know - how your application behaves, and that's where Web Vitals help us get a - clear overview of how our app is doing. - speakers: - - Erick Tamayo - -- title: "Making slow responses seem fast with stale-while-revalidate" - time: 12:15 PM - type: lightning - description: >- - The Cache-Control header has been around since HTTP/1.1 in 1997, yet for - many of us, it's not something we think about every day. The - stale-while-revalidate extension was proposed as early as 2010, but was only - widely supported in modern browsers in 2019. In this talk, I will show you - the power of stale-while-revalidate and how you can take advantage of it in - your Remix project to make your slow responses seem really fast! - speakers: - - Scott Smerchek - -- title: "Building tech for social good with low-code tools" - time: 2:25 PM - type: lightning - description: >- - In this talk we are going to be talking about how to build hybrid apps that - use a combination of frameworks like Remix and mixing them with no-code - backends like Zapier and Airtable, so that they can be managed and modified - by non-technical people. - - - I will specifically go over how I replaced the admissions process at my - children's preschool with a website and made them paperfree. - speakers: - - Vic Vijayakumar - -- title: "Expanding Remix with Rust" - time: 2:30 PM - type: lightning - description: >- - Remix's unique use of Loader and Action functions offers the unique - opportunity to expand your data processing with Rust. Rust offers near - native performance, memory safety through either the Node FFI or via - compilation into WebAssembly. Learn the tricks to setup your Rust project to - work with Remix, either on the server or the client, and take advantage of - the most loved language with your favorite web framework! - speakers: - - Ben Wishovich - -- title: "Full Stack Fast: Data on the Edge" - time: 2:35 PM - type: lightning - description: >- - Why force your users to settle for either loading skeletons or slow page - renders? Remix can bring your application rendering to the edge, but what - about your data? Why should every request have to call back to a single - database cluster in Virginia? For the best performance and experience for - your users, store your data on the edge, alongside the rest of your - application. - - - We'll discuss how the original colocated server and database configuration - worked, how it evolved with Jamstack, improved with next-gen data services, - and how today's technology supports a new architecture altogether. But - distributed systems are notoriously hard to design for, and edge-based - storage is no different, with the challenges of synchronicity being a - particularly difficult problem. I'll highlight the benefits of edge-based - storage, how it compares to the other options, and I'll showcase a truly - global Remix application built with Cloudflare's KV, Durable Objects and R2. - speakers: - - Greg Brimble - -- title: Remix your UI & UX to another level - time: 2:45 PM - type: regular - description: >- - Build performant web apps with a full-stack framework, Remix. Remix focuses - on the UI to enjoy fast & resilient UX. Experience the "Remix magic" that - enables no fetching & pre-fetch all in parallel before users make actions. - As Remix focuses on UI & UX, why not share the "Remix magic" with the - business users? In this talk, we're going to see together the combination of - the new generation of a full-stack framework, Remix & a visual editor - integrated headless CMS (Storyblok). Are you ready to explore a whole new - level of experience? - speakers: - - Arisa Fukuzaki - -- title: "Magically create forms + actions with Remix Forms" - time: 3:10 PM - type: regular - description: >- - One of the beautiful things about Remix is how easy it is to enhance it to - make our lives easier. In this talk, I'll show you how I built [Remix - Forms](https://remix-forms.seasoned.cc/) and how I use it to: - - - Code only the parts of my forms that stray from our standard UI. The rest - is magically rendered for me. - - - Never have to think again about client-side + server-side validations, - pending indicators, and focus management (with focus on the first field with - error even for server-side failures!) - - - Get form data, validate values, redirect or return errors with one helper. - I focus on the mutation, not on the wiring. - - - Catch any typo or mistake right away with bulletproof typing, even for - custom inputs. - - - Enjoy the autocomplete magic that comes along with it :) - speakers: - - Daniel Weinmann - -- title: "Incremental Remix" - time: 3:35 PM - type: regular - description: >- - Remix is fantastic for building brand-new apps. But the truth is most of us - are slogging away on crusty old ones. How can we incorporate Remix into our - stacks without rewriting everything? And how can we effectively sell our - teams on the benefits of adoption? In this talk we'll explore some - strategies that will let you gradually adopt Remix, progressively enhancing - your tech stack. - speakers: - - Jon Jensen - -- title: "Outstanding Search Experiences with Remix and Algolia" - time: 4:25 PM - type: regular - description: >- - Outstanding search starts with two principles: immediate feedback and - relevant results. - - Search-as-you-type experiences have become the standard since Google - introduced Google Suggest and Google Instant on their search page in the - 2000s. Users not only love the immediate feedback of instant experiences, - they expect it. They also expect search to be excellent at understanding - their intent, even when they misspell or forget words. - - Services like Algolia are designed to deliver instant, as-you-type, relevant - results right from the first keystrokes. But what happens when the user's - network is slow? What's relevant when the user didn't express intent yet? In - this talk, we'll see how you can combine Algolia's client-side search with - the power of Remix's server runtime to create snappy and delightful yet - reliable and resilient search experiences that serve everyone. - speakers: - - Sarah Dayan - -- title: "Switching to Remix at Neighbor" - time: 4:50 PM - type: regular - description: >- - Neighbor is a marketplace that allows you to make extra cash by storing your - neighbors' things in your extra space. After several years of using a - standard React frontend generated by create-react-app, we've decided to move - to Remix. I will discuss some of the crazy things we've done at Neighbor to - work around the limitations of a standard CRA-generated application, why we - chose to use Remix over other alternatives, and discuss some of the gotchas - and learning that came out of the migration. If you work at a medium to - large business and are interested in moving to Remix, this talk is - especially for you. I will mostly stick to big picture concepts rather than - diving deep into the code. - speakers: - - Dennis Beatty - -- title: Remix & high performance eCommerce - type: backup - description: >- - Performances are key. That statement is true for any web application but - even more for eCommerce applications that convert performances into revenue. - - Why are eCommerce projects more complex than others? What are the key topics - and the special things that you need to take into account when building an - eCommerce application in 2022. - - In this talk we will deep dive into all the things that must be dynamic and - how to achieve performances. - - All explained with a Remix project example. - speakers: - - Sébastien Morel - -- title: "How To WebPageTest" - time: 9:35 AM - type: regular - description: >- - You cannot improve what you do not measure, and measuring page performance - is at the heart of providing marvellous user experiences. "How To - WebPageTest" is a talk where I will demonstrate how modern profiling using - WebPageTest will provide the best insights. I'll show you tips and tricks on - how to interpret the results, and I'll also expose you to key features that - are best in class in performance testing. - speakers: - - Henri Helvetica - -- title: "Remixing a Symfony" - type: backup - description: >- - In late 2020, I ran a Lighthouse test on a simple content page on Harvie, - our farm management platform and Symfony app, and received a performance - score of 31/100. The JavaScript bundle, the API requests, the database - lookups, even with minimal UI to render, had a baseline score in the - thirties! Along with customer feedback, this helped to catalyze a renewed - commitment to performance at Harvie. Through numerous discussions, we walked - through each step of page load, from networking to rendering, and identified - where we could improve. After a year of rewrites and upgrades, our remaining - detriment to overall performance was our frontend. We had been converting - our Symfony twig templates into React SPA components and fell into the - common problem of creating "request waterfalls", while our user had to stare - at a loading screen. We needed a change, and for us, that was Remix. In this - talk, I'll walk you through our team's journey with performance and how - Remix has become a natural progression of that. - speakers: - - Emily Kauffman - -- title: "Intro To Remix - Working with Nested Routes and Parameterized Routes" - type: backup - description: >- - We will walk through a simple demonstration of a remix application using - nested routes and parameterized routes. The use of nested routes helps me - with component design and separation when architecting an application. - Parameterized routes / Dynamic Routes contain state information that can - through the parameters that are defined on the route. This provides powerful - flexibility when designing your app and app's components. Putting the two - together in an simple solution to be a reference when you build something - amazing. - speakers: - - Aaron K Saunders