From a10293a4137535f75fa33af1086a03ffaf933086 Mon Sep 17 00:00:00 2001 From: Alex Sanders Date: Tue, 25 Apr 2023 17:00:06 +0100 Subject: [PATCH 01/10] add subdir components --- src/_site/components/sub_dir/SubDir.island.svelte | 5 +++++ src/_site/routes/nested-islands.svelte | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 src/_site/components/sub_dir/SubDir.island.svelte diff --git a/src/_site/components/sub_dir/SubDir.island.svelte b/src/_site/components/sub_dir/SubDir.island.svelte new file mode 100644 index 0000000..b6c6eb7 --- /dev/null +++ b/src/_site/components/sub_dir/SubDir.island.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/_site/routes/nested-islands.svelte b/src/_site/routes/nested-islands.svelte index 5c52bd5..1ab54a7 100644 --- a/src/_site/routes/nested-islands.svelte +++ b/src/_site/routes/nested-islands.svelte @@ -1,9 +1,11 @@ Example of nested islands. + From d379256e550d31519f146bc9e2add32397770f7e Mon Sep 17 00:00:00 2001 From: Alex Sanders Date: Tue, 25 Apr 2023 17:00:27 +0100 Subject: [PATCH 02/10] multiple isntances of component on page --- src/_site/routes/nested-islands.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_site/routes/nested-islands.svelte b/src/_site/routes/nested-islands.svelte index 1ab54a7..a3ac124 100644 --- a/src/_site/routes/nested-islands.svelte +++ b/src/_site/routes/nested-islands.svelte @@ -8,4 +8,5 @@ Example of nested islands. + From 5c0b32ca30802e0d2bb22d9219f2fafeecb78ca3 Mon Sep 17 00:00:00 2001 From: Alex Sanders Date: Tue, 25 Apr 2023 17:00:56 +0100 Subject: [PATCH 03/10] rename `routes` to match export name --- src/build.ts | 2 +- .../{routes.ts => build_routes.ts} | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) rename src/esbuild_plugins/{routes.ts => build_routes.ts} (77%) diff --git a/src/build.ts b/src/build.ts index 65d1369..8bf4f1d 100644 --- a/src/build.ts +++ b/src/build.ts @@ -1,7 +1,7 @@ import * as esbuild from "https://deno.land/x/esbuild@v0.17.16/mod.js"; import { svelte_components } from "./esbuild_plugins/svelte_components.ts"; import { svelte_internal } from "./esbuild_plugins/svelte_internal.ts"; -import { build_routes } from "./esbuild_plugins/routes.ts"; +import { build_routes } from "./esbuild_plugins/build_routes.ts"; import { ensureDir } from "https://deno.land/std@0.177.0/fs/ensure_dir.ts"; import { parse } from "https://deno.land/std@0.177.0/flags/mod.ts"; import { serve } from "https://deno.land/std@0.177.0/http/server.ts"; diff --git a/src/esbuild_plugins/routes.ts b/src/esbuild_plugins/build_routes.ts similarity index 77% rename from src/esbuild_plugins/routes.ts rename to src/esbuild_plugins/build_routes.ts index b3ff278..c9e7f67 100644 --- a/src/esbuild_plugins/routes.ts +++ b/src/esbuild_plugins/build_routes.ts @@ -9,9 +9,7 @@ interface SSROutput { css?: { code: string }; } -export const build_routes = ( - { base_path }: { base_path: string }, -): Plugin => ({ +export const build_routes: Plugin = { name: "mononykus/build-routes", setup(build) { build.onEnd(async (result) => { @@ -29,6 +27,14 @@ export const build_routes = ( }; const { html, css: _css, head } = module.default.render(); + + // remove any duplicate module imports (in cases where a page uses an island more than once) + const deduped_head = Array.from( + new Set( + head.match(/ @@ -61,23 +50,15 @@ const template = ({ css, head, html, hydrator }: TemplateOptions) => ` `; -const island_hydrator = (base = "") => ` - const component_path = "${base}"; - const hydrate_island = ${hydrate_island.toString()}; - document.querySelectorAll("one-claw[name]:not(one-claw one-claw)").forEach(hydrate_island); -`; - -export const get_route_html = ({ html, css, head, base_path }: { +export const get_route_html = ({ html, css, head }: { html: string; css: string; head: string; - base_path?: string; }) => { const page = template({ css, head, html, - hydrator: island_hydrator(normalize(`/${base_path}/components/`)), }); try { diff --git a/src/esbuild_plugins/svelte_components.ts b/src/esbuild_plugins/svelte_components.ts index d130085..04f5bd8 100644 --- a/src/esbuild_plugins/svelte_components.ts +++ b/src/esbuild_plugins/svelte_components.ts @@ -4,6 +4,7 @@ import { resolve, } from "https://deno.land/std@0.177.0/path/mod.ts"; import type { Plugin } from "https://deno.land/x/esbuild@v0.17.16/mod.js"; +import { normalize } from "https://deno.land/std@0.177.0/path/mod.ts"; import { compile } from "npm:svelte/compiler"; const filter = /\.svelte$/; @@ -12,19 +13,32 @@ const name = "mononykus/svelte"; /** force wrapping the actual component in a synthetic one */ const one_claw_synthetic = "?one-claw-synthetic"; -const OneClaw = ({ path, name }: { path: string; name: string }) => +const OneClaw = ( + { path, name, module_src }: { + path: string; + name: string; + module_src: string; + }, +) => ` - - - - -`; + + + + + + + + +`; -export const svelte_components: Plugin = { +export const svelte_components = ( + site_dir: string, + base_path: string, +): Plugin => ({ name, setup(build) { const generate = build.initialOptions.write ? "dom" : "ssr"; @@ -61,8 +75,14 @@ export const svelte_components: Plugin = { .replace(/(\.island)?\.svelte$/, "") .replaceAll(/(\.|\W)/g, "_"); + const module_src = normalize("/" + base_path + path.split(site_dir)[1]) + .replace( + /svelte$/, + "js", + ); + const source = suffix === one_claw_synthetic - ? OneClaw({ path, name }) + ? OneClaw({ path, name, module_src }) : await Deno.readTextFile(path); const { js: { code } } = compile(source, { @@ -74,7 +94,38 @@ export const svelte_components: Plugin = { filename: basename(path), }); + if (suffix === one_claw_synthetic) { + const x = () => { + try { + document.querySelectorAll( + `one-claw[name='${name}']:not(one-claw one-claw)`, + ).forEach((target, i) => { + const load = performance.now(); + console.group( + `Hydrating %c${name}%c (instance #${(i + 1)})`, + "color: orange", + "color: reset", + ); + console.log(target); + const props = JSON.parse(target.getAttribute("props") ?? "{}"); + // new component({ target, props, hydrate: true }); + console.log( + `Done in %c${ + Math.round((performance.now() - load) * 1000) / 1000 + }ms`, + "color: orange", + ); + console.groupEnd(); + }); + } catch (_) { + console.error(_); + } + }; + + return ({ contents: code + x.toString() }); + } + return ({ contents: code }); }); }, -}; +}); From 39657bc6fa22ee2370763ff9728b1fec4b92ef45 Mon Sep 17 00:00:00 2001 From: Alex Sanders Date: Fri, 28 Apr 2023 12:38:03 +0100 Subject: [PATCH 05/10] use `onMount` --- src/_site/components/GreenThenPink.island.svelte | 14 ++++++++------ src/_site/components/RedThenBlue.island.svelte | 13 +++++++------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/_site/components/GreenThenPink.island.svelte b/src/_site/components/GreenThenPink.island.svelte index f397c9e..0bd8bd3 100644 --- a/src/_site/components/GreenThenPink.island.svelte +++ b/src/_site/components/GreenThenPink.island.svelte @@ -1,13 +1,15 @@

green then pink

diff --git a/src/_site/components/RedThenBlue.island.svelte b/src/_site/components/RedThenBlue.island.svelte index ddc51e2..35be48b 100644 --- a/src/_site/components/RedThenBlue.island.svelte +++ b/src/_site/components/RedThenBlue.island.svelte @@ -1,15 +1,16 @@

red then blue

From cda5745a01b60a4f4fea439c7142bb053659a345 Mon Sep 17 00:00:00 2001 From: Alex Sanders Date: Fri, 28 Apr 2023 12:39:20 +0100 Subject: [PATCH 06/10] =?UTF-8?q?make=20sure=20deduping=20doesn=E2=80=99t?= =?UTF-8?q?=20strip=20all=20non-scripts=20out?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/esbuild_plugins/build_routes.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/esbuild_plugins/build_routes.ts b/src/esbuild_plugins/build_routes.ts index c9e7f67..6212494 100644 --- a/src/esbuild_plugins/build_routes.ts +++ b/src/esbuild_plugins/build_routes.ts @@ -29,11 +29,17 @@ export const build_routes: Plugin = { const { html, css: _css, head } = module.default.render(); // remove any duplicate module imports (in cases where a page uses an island more than once) - const deduped_head = Array.from( - new Set( - head.match(/