@ilha/astro 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -1,2 +1,15 @@
1
- declare const _default: (element: HTMLElement) => (Component: unknown, props: Record<string, unknown>, slotted: Record<string, string>, _metadata: Record<string, string>) => Promise<void>;
2
- export default _default;
1
+ import type { View } from "ilha";
2
+ /** JSON-serializable data — Astro props cross the client boundary serialized. */
3
+ type Json = string | number | boolean | null | Json[] | {
4
+ [key: string]: Json;
5
+ };
6
+ /** Props passed to a hydrated island: Astro's serialized props plus slotted
7
+ * content re-keyed as `children`. */
8
+ type IslandProps = Record<string, Json>;
9
+ export type { IslandProps };
10
+ /** An ilha component: a function of props producing a view. The integration's
11
+ * `check()` validates the component at build time, so no runtime guard is
12
+ * needed here. */
13
+ type IslandComponent = (props: IslandProps) => View | undefined | Promise<View | undefined>;
14
+ declare const mountIsland: (element: HTMLElement) => (Component: IslandComponent, props: IslandProps, slotted: Record<string, string>, _metadata: Record<string, string>) => void;
15
+ export default mountIsland;
package/dist/client.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { mount } from "ilha";
2
2
 
3
3
  //#region src/client.ts
4
- var client_default = (element) => async (Component, props, slotted, _metadata) => {
5
- if (typeof Component !== "function") return;
4
+ const mountIsland = (element) => (Component, props, slotted, _metadata) => {
6
5
  const merged = { ...props };
7
6
  for (const [name, value] of Object.entries(slotted ?? {})) merged[name === "default" ? "children" : name] = value;
8
7
  const nested = element.querySelector("[data-ilha]");
@@ -11,4 +10,4 @@ var client_default = (element) => async (Component, props, slotted, _metadata) =
11
10
  };
12
11
 
13
12
  //#endregion
14
- export { client_default as default };
13
+ export { mountIsland as default };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export interface IlhaIntegrationOptions {
3
3
  include?: string | string[];
4
4
  exclude?: string | string[];
5
5
  }
6
- export declare function getRenderer(): AstroRenderer;
6
+ export declare const getRenderer: () => AstroRenderer;
7
7
  /**
8
8
  * Vite's dependency optimizer otherwise inlines peer `ilha` into prebundled
9
9
  * consumers (Areia, etc.) while the app loads workspace/linked `ilha` via
@@ -11,17 +11,17 @@ export declare function getRenderer(): AstroRenderer;
11
11
  *
12
12
  * `resolve.dedupe` + `optimizeDeps.exclude` keep a single module instance.
13
13
  */
14
- export declare function getViteConfig(options?: IlhaIntegrationOptions): {
14
+ export declare const getViteConfig: (options?: IlhaIntegrationOptions) => {
15
+ optimizeDeps: {
16
+ exclude: string[];
17
+ };
15
18
  plugins: {
19
+ load(id: string): string | undefined;
16
20
  name: string;
17
21
  resolveId(id: string): "\0virtual:@ilha/astro/options" | undefined;
18
- load(id: string): string | undefined;
19
22
  }[];
20
23
  resolve: {
21
24
  dedupe: string[];
22
25
  };
23
- optimizeDeps: {
24
- exclude: string[];
25
- };
26
26
  };
27
27
  export default function ilhaIntegration(options?: IlhaIntegrationOptions): AstroIntegration;
package/dist/index.js CHANGED
@@ -1,44 +1,40 @@
1
1
  //#region src/index.ts
2
2
  const OPTIONS_MODULE = "virtual:@ilha/astro/options";
3
- function globToRegExp(pattern) {
3
+ const objectTag = (value) => Object.prototype.toString.call(value);
4
+ const isString = (value) => objectTag(value) === "[object String]";
5
+ const globToRegExp = (pattern) => {
4
6
  let source = "^";
5
- for (let i = 0; i < pattern.length; i++) {
7
+ for (let i = 0; i < pattern.length; i += 1) {
6
8
  const char = pattern[i];
7
9
  if (char === "*") {
8
10
  if (pattern[i + 1] === "*") {
9
- i++;
11
+ i += 1;
10
12
  if (pattern[i + 1] === "/") {
11
- i++;
13
+ i += 1;
12
14
  source += "(?:.*/)?";
13
15
  } else source += ".*";
14
16
  } else source += "[^/]*";
15
17
  } else if (char === "?") source += "[^/]";
16
- else source += char.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
18
+ else source += char.replaceAll(/[\\^$.*+?()[\]{}|]/gu, "\\$&");
17
19
  }
18
- return new RegExp(`${source}$`);
19
- }
20
- function patternList(patterns) {
21
- return (typeof patterns === "string" ? [patterns] : patterns ?? []).map(globToRegExp).join(",");
22
- }
23
- function optionsPlugin(options) {
24
- return {
25
- name: "@ilha/astro:options",
26
- resolveId(id) {
27
- return id === OPTIONS_MODULE ? `\0${OPTIONS_MODULE}` : void 0;
28
- },
29
- load(id) {
30
- if (id !== `\0${OPTIONS_MODULE}`) return;
31
- return `const include=[${patternList(options.include)}],exclude=[${patternList(options.exclude)}];export default id=>(!include.length||include.some(pattern=>pattern.test(id)))&&!exclude.some(pattern=>pattern.test(id));`;
32
- }
33
- };
34
- }
35
- function getRenderer() {
36
- return {
37
- name: "@ilha/astro",
38
- clientEntrypoint: "@ilha/astro/client",
39
- serverEntrypoint: "@ilha/astro/server"
40
- };
41
- }
20
+ return new RegExp(`${source}$`, "u");
21
+ };
22
+ const patternList = (patterns) => (isString(patterns) ? [patterns] : patterns ?? []).map(globToRegExp).join(",");
23
+ const optionsPlugin = (options) => ({
24
+ load(id) {
25
+ if (id !== `\0${OPTIONS_MODULE}`) return;
26
+ return `const include=[${patternList(options.include)}],exclude=[${patternList(options.exclude)}];export default id=>(!include.length||include.some(pattern=>pattern.test(id)))&&!exclude.some(pattern=>pattern.test(id));`;
27
+ },
28
+ name: "@ilha/astro:options",
29
+ resolveId(id) {
30
+ return id === OPTIONS_MODULE ? `\0${OPTIONS_MODULE}` : void 0;
31
+ }
32
+ });
33
+ const getRenderer = () => ({
34
+ clientEntrypoint: "@ilha/astro/client",
35
+ name: "@ilha/astro",
36
+ serverEntrypoint: "@ilha/astro/server"
37
+ });
42
38
  /**
43
39
  * Vite's dependency optimizer otherwise inlines peer `ilha` into prebundled
44
40
  * consumers (Areia, etc.) while the app loads workspace/linked `ilha` via
@@ -46,20 +42,18 @@ function getRenderer() {
46
42
  *
47
43
  * `resolve.dedupe` + `optimizeDeps.exclude` keep a single module instance.
48
44
  */
49
- function getViteConfig(options = {}) {
50
- return {
51
- plugins: [optionsPlugin(options)],
52
- resolve: { dedupe: ["ilha"] },
53
- optimizeDeps: { exclude: ["ilha"] }
54
- };
55
- }
45
+ const getViteConfig = (options = {}) => ({
46
+ optimizeDeps: { exclude: ["ilha"] },
47
+ plugins: [optionsPlugin(options)],
48
+ resolve: { dedupe: ["ilha"] }
49
+ });
56
50
  function ilhaIntegration(options = {}) {
57
51
  return {
58
- name: "@ilha/astro",
59
52
  hooks: { "astro:config:setup": ({ addRenderer, updateConfig }) => {
60
53
  addRenderer(getRenderer());
61
54
  updateConfig({ vite: getViteConfig(options) });
62
- } }
55
+ } },
56
+ name: "@ilha/astro"
63
57
  };
64
58
  }
65
59
 
package/dist/server.js CHANGED
@@ -2,42 +2,55 @@ import { renderToString } from "ilha";
2
2
 
3
3
  //#region src/server.ts
4
4
  let componentFilter;
5
- function getComponentFilter() {
6
- return componentFilter ??= import("virtual:@ilha/astro/options").then(({ default: filter }) => filter).catch(() => () => true);
7
- }
8
- function isAstroRenderable(value) {
9
- return !!value && typeof value === "object" && typeof value.render === "function";
10
- }
11
- async function resolveAstroRenderable(value) {
5
+ const objectTag = (value) => Object.prototype.toString.call(value);
6
+ const isFunction = (value) => {
7
+ const tag = objectTag(value);
8
+ return tag === "[object Function]" || tag === "[object AsyncFunction]" || tag === "[object GeneratorFunction]";
9
+ };
10
+ const getComponentFilter = async () => {
11
+ componentFilter ??= (async () => {
12
+ try {
13
+ const { default: filter } = await import("virtual:@ilha/astro/options");
14
+ return filter;
15
+ } catch {
16
+ return () => true;
17
+ }
18
+ })();
19
+ return await componentFilter;
20
+ };
21
+ const isAstroRenderable = (value) => value !== null && "render" in new Object(value);
22
+ const resolveAstroRenderable = async (value) => {
12
23
  let out = "";
13
24
  await value.render({ write(chunk) {
14
- if (chunk != null) out += String(chunk);
25
+ out += chunk;
15
26
  } });
16
27
  return out;
17
- }
18
- async function resolvePropValue(value) {
28
+ };
29
+ const resolvePropValue = async (value) => {
19
30
  if (isAstroRenderable(value)) return await resolveAstroRenderable(value);
20
31
  if (Array.isArray(value)) return Promise.all(value.map(resolvePropValue));
21
32
  return value;
22
- }
23
- async function mergeProps(props, slots) {
24
- const resolved = {};
25
- for (const [key, value] of Object.entries(props)) resolved[key] = await resolvePropValue(value);
33
+ };
34
+ const mergeProps = async (props, slots) => {
35
+ const entries = Object.entries(props).filter((entry) => entry[1] !== void 0);
36
+ const resolvedValues = await Promise.all(entries.map(([, value]) => resolvePropValue(value)));
37
+ const resolved = Object.fromEntries(entries.map(([key], index) => [key, resolvedValues[index]]));
26
38
  for (const [name, value] of Object.entries(slots)) resolved[name === "default" ? "children" : name] = value;
27
39
  return resolved;
28
- }
29
- async function check(Component, _props, _slots, metadata) {
40
+ };
41
+ const check = async (Component, _props, _slots, metadata) => {
30
42
  if (metadata?.componentUrl && !(await getComponentFilter())(metadata.componentUrl)) return false;
31
- return typeof Component === "function";
32
- }
33
- async function renderToStaticMarkup(Component, props, slots, metadata) {
34
- if (typeof Component !== "function") throw new Error(`[@ilha/astro] Unable to render "${metadata?.displayName ?? "component"}" — expected a function.`);
43
+ return isFunction(Component);
44
+ };
45
+ const renderToStaticMarkup = async (Component, props, slots, metadata) => {
46
+ if (!isFunction(Component)) throw new TypeError(`[@ilha/astro] Unable to render "${metadata?.displayName ?? "component"}" — expected a function.`);
35
47
  const merged = await mergeProps(props, slots);
36
- return { html: await renderToString(() => Component(merged)) };
37
- }
48
+ const render = Component;
49
+ return { html: await renderToString(() => render(merged)) };
50
+ };
38
51
  const renderer = {
39
- name: "@ilha/astro",
40
52
  check,
53
+ name: "@ilha/astro",
41
54
  renderToStaticMarkup
42
55
  };
43
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ilha/astro",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Astro integration for Ilha islands",
5
5
  "keywords": [
6
6
  "astro-component",
@@ -55,10 +55,10 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "astro": "^7.2.9",
58
- "ilha": "0.14.2"
58
+ "ilha": "0.14.4"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "astro": "^7.2.9",
62
- "ilha": "^0.14.2"
62
+ "ilha": "^0.14.4"
63
63
  }
64
64
  }