cirrojs 0.0.6 → 0.0.8

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/CHANGELOG.md CHANGED
@@ -13,6 +13,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
13
13
 
14
14
  ## [Unreleased]
15
15
 
16
+ ## [0.0.8] - 2026-06-21
17
+
18
+ ### Added
19
+ - `FileRoute`, a new member of `AnyRoute` alongside `StaticRoute` and `DynamicRoute`, for generating arbitrary text files.
20
+ - `markdownToText`, a `cirrojs/server` function that converts Markdown to plain text, primarily for generating search indexes.
21
+ - `Registry` type and `runWithRegistry`, exported from the package entry point. `runWithRegistry` runs a render callback in its own registry context and returns both the result and the collected registry.
22
+
23
+ ### Changed
24
+ - `StaticRoute` and `DynamicRoute` now require a `type` property. With it, route definitions are type-inferred without wrapping them in `route()`.
25
+ - Renamed `createMarkdown` to `createMarkdownProcessor`.
26
+ - The CSS registry is now scoped per render via `AsyncLocalStorage` instead of a shared module-global map, preventing styles from different routes from leaking into one another.
27
+
28
+ ### Removed
29
+ - Removed `initCssRegistry` and `getCssRegistry`. Use `runWithRegistry` instead. Sites must re-export `runWithRegistry` from their `routes.ts` in place of the two removed functions.
30
+ - Removed the `route`, `expandRoutes`, and `urlToFilePath` exports, along with the `ResolvedPage` type. Route definitions no longer need `route()` thanks to the required `type` property.
31
+
32
+ ## [0.0.7] - 2026-06-19
33
+
34
+ ### Added
35
+ - The `Island` component now accepts an optional `className` prop, which is applied to its top-level wrapper element.
36
+
16
37
  ## [0.0.6] - 2026-06-19
17
38
 
18
39
  ### Fixed
@@ -46,7 +67,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
46
67
  ## 0.0.1 - 2026-06-15
47
68
  - initial release
48
69
 
49
- [Unreleased]: https://github.com/osawa-naotaka/cirro/compare/v0.0.6...HEAD
70
+ [Unreleased]: https://github.com/osawa-naotaka/cirro/compare/v0.0.8...HEAD
71
+ [0.0.8]: https://github.com/osawa-naotaka/cirro/compare/v0.0.7...v0.0.8
72
+ [0.0.7]: https://github.com/osawa-naotaka/cirro/compare/v0.0.6...v0.0.7
50
73
  [0.0.6]: https://github.com/osawa-naotaka/cirro/compare/v0.0.5...v0.0.6
51
74
  [0.0.5]: https://github.com/osawa-naotaka/cirro/compare/v0.0.4...v0.0.5
52
75
  [0.0.4]: https://github.com/osawa-naotaka/cirro/compare/v0.0.3...v0.0.4
package/dist/cli.js CHANGED
@@ -1 +1 @@
1
- import{i as e,r as t,s as n,t as r}from"./router-52EuPj-F.js";import{Fragment as i,createElement as a}from"react";import{renderToStaticMarkup as o}from"react-dom/server";import{dirname as s,join as c,resolve as l}from"node:path";import{mkdir as u,readFile as d,writeFile as f}from"node:fs/promises";import{build as p,createServer as m,createServerModuleRunner as h}from"vite";import{createServer as g}from"node:http";function _(e,t,n){return a(i,null,e,a(`script`,{async:!0,type:`module`,src:t,key:`cirro-client`}),a(`link`,{rel:`stylesheet`,href:n,precedence:`default`,key:`cirro-css`}))}function v(e){for(let t of e.plugins){let e=t.api;if(t.name===`cirro`&&e?.options)return e.options}throw Error(`cirro: plugin not found in Vite config (did you add cirro() to plugins?)`)}async function y(){await p();let i=await m({server:{middlewareMode:!0,hmr:!1},appType:`custom`}),a=h(i.environments.ssr);try{let p=i.config,m=v(p),h=p.root,g=l(h,p.build.outDir),y=l(h,m.routes),b=JSON.parse(await d(c(g,`.vite/manifest.json`),`utf-8`))[`virtual:cirro/client`];if(!b)throw Error(`cirro: manifest entry "virtual:cirro/client" not found`);let x=`/${b.file}`,{routes:S,getCssRegistry:C,initCssRegistry:w}=await a.import(y);for(let i of r(S)){if(i.isCss){w(),o(i.render());let e=n(C()),r=c(g,t(i.url));await u(s(r),{recursive:!0}),await f(r,e),console.log(`wrote ${r} (url: ${i.url})`);continue}let r=`<!DOCTYPE html>${o(_(i.render(),x,i.cssPath))}`,a=c(g,e(i.url));await u(s(a),{recursive:!0}),await f(a,r),console.log(`wrote ${a} (url: ${i.url})`)}}finally{await i.close()}}function b(e,t){let n=[t,t.replaceAll(`\\`,`/`)];for(let t of Object.values(e.environments)){let e=t.moduleGraph;if(!e)continue;let r=new Set,i=t=>{if(!r.has(t)){r.add(t),e.invalidateModule(t);for(let e of t.importers)i(e)}};for(let t of n){let n=e.getModulesByFile(t);if(n)for(let e of n)i(e)}}}async function x(e=5173){let t=await m({server:{middlewareMode:!0},appType:`custom`}),i=h(t.environments.ssr),a=v(t.config),c=t.config.root,u=l(c,a.routes),d=s(l(c,a.islands)).replaceAll(`\\`,`/`),f=g((e,a)=>{t.middlewares(e,a,async()=>{let s=e.url??`/`;try{let{routes:e,getCssRegistry:c,initCssRegistry:l}=await i.import(u),d=r(e);if(s.endsWith(`.css`)){let e=d.find(e=>e.isCss&&e.url===s);if(!e){a.statusCode=404,a.end();return}l(),o(e.render());let t=n(c());a.statusCode=200,a.setHeader(`Content-Type`,`text/css; charset=utf-8`),a.end(t);return}let f=new URL(s,`http://localhost`).pathname.replace(/\/+$/,``)||`/`,p=d.find(e=>(e.url.replace(/\/+$/,``)||`/`)===f);if(!p){a.statusCode=404,a.setHeader(`Content-Type`,`text/html; charset=utf-8`),a.end(`<!DOCTYPE html><meta charset="utf-8"><h1>404 Not Found</h1>`);return}let m=`<!DOCTYPE html>${o(_(p.render(),`/@id/__x00__virtual:cirro/client`,p.cssPath))}`;m=await t.transformIndexHtml(s,m),a.statusCode=200,a.setHeader(`Content-Type`,`text/html; charset=utf-8`),a.end(m)}catch(e){a.statusCode=500,a.end(String(e))}})}),p=`${l(c,a.watchDir??`./src`).replaceAll(`\\`,`/`).replace(/\/+$/,``)}/`;t.watcher.on(`change`,e=>{let n=e.replaceAll(`\\`,`/`);n.startsWith(d)||n.startsWith(p)&&(b(t,e),t.ws.send({type:`full-reload`}))}),f.listen(e,()=>{console.log(`cirro dev: http://localhost:${e}`)})}async function S(e){let t=e[0];t===`dev`?await x():t===`build`?await y():(console.error(`usage: cirro <dev|build>`),process.exit(1))}export{S as main};
1
+ import{r as e}from"./css-L9LEkQky.js";import{Fragment as t,createElement as n}from"react";import{renderToStaticMarkup as r}from"react-dom/server";import{dirname as i,extname as a,join as o,resolve as s}from"node:path";import{mkdir as c,readFile as l,writeFile as u}from"node:fs/promises";import{build as d,createServer as f,createServerModuleRunner as p}from"vite";import{createServer as m}from"node:http";function h(e){let t=[];for(let n of e)switch(n.type){case`static`:t.push({type:`html`,path:n.path,cssPath:o(n.path,`index.css`),render:()=>n.component({params:{}})}),t.push({type:`css`,path:o(n.path,`index.css`),render:()=>n.component({params:{}})});break;case`dynamic`:for(let e of n.getStaticPaths())t.push({type:`html`,path:n.path(e),cssPath:n.cssPath,render:()=>n.component({params:e})});t.push({type:`css`,path:n.cssPath,render:()=>n.component({params:n.getStaticPaths()[0]})});break;case`file`:t.push({type:`file`,path:n.path,ext:a(n.path),render:()=>n.component({params:{}})});break}return t}function g(e){return e===`/`?`index.html`:`${e.replace(/^\/+|\/+$/g,``)}/index.html`}function _(e){return e===`/`?`index.css`:`${e.replace(/^\/+|\/+$/g,``)}`}function v(e,r,i){return n(t,null,e,n(`script`,{async:!0,type:`module`,src:r,key:`cirro-client`}),n(`link`,{rel:`stylesheet`,href:i,precedence:`default`,key:`cirro-css`}))}function y(e){for(let t of e.plugins){let e=t.api;if(t.name===`cirro`&&e?.options)return e.options}throw Error(`cirro: plugin not found in Vite config (did you add cirro() to plugins?)`)}async function b(){await d();let t=await f({server:{middlewareMode:!0,hmr:!1},appType:`custom`}),n=p(t.environments.ssr);try{let a=t.config,d=y(a),f=a.root,p=s(f,a.build.outDir),m=s(f,d.routes),b=JSON.parse(await l(o(p,`.vite/manifest.json`),`utf-8`))[`virtual:cirro/client`];if(!b)throw Error(`cirro: manifest entry "virtual:cirro/client" not found`);let x=`/${b.file}`,{routes:S,runWithRegistry:C}=await n.import(m);for(let t of h(S))switch(t.type){case`css`:{let{registry:n}=C(()=>r(t.render())),a=e(n),s=o(p,_(t.path));await c(i(s),{recursive:!0}),await u(s,a),console.log(`wrote ${s} (url: ${t.path})`);break}case`html`:{let{result:e}=C(()=>`<!DOCTYPE html>${r(v(t.render(),x,t.cssPath))}`),n=o(p,g(t.path));await c(i(n),{recursive:!0}),await u(n,e),console.log(`wrote ${n} (url: ${t.path})`);break}case`file`:{let e=t.render(),n=o(p,t.path);await c(i(n),{recursive:!0}),await u(n,e),console.log(`wrote ${n} (url: ${t.path})`);break}}}finally{await t.close()}}const x=[[`.aac`,`audio/aac`],[`.abw`,`application/x-abiword`],[`.arc`,`application/x-freearc`],[`.avi`,`video/x-msvideo`],[`.azw`,`application/vnd.amazon.ebook`],[`.bin`,`application/octet-stream`],[`.bmp`,`image/bmp`],[`.bz`,`application/x-bzip`],[`.bz2`,`application/x-bzip2`],[`.csh`,`application/x-csh`],[`.css`,`text/css`],[`.csv`,`text/csv`],[`.doc`,`application/msword`],[`.docx`,`application/vnd.openxmlformats-officedocument.wordprocessingml.document`],[`.eot`,`application/vnd.ms-fontobject`],[`.epub`,`application/epub+zip`],[`.gz`,`application/gzip`],[`.gif`,`image/gif`],[`.htm`,`text/html`],[`.html`,`text/html`],[`.ico`,`image/vnd.microsoft.icon`],[`.ics`,`text/calendar`],[`.jar`,`application/java-archive`],[`.jpeg`,`image/jpeg`],[`.jpg`,`image/jpeg`],[`.js`,`text/javascript`],[`.json`,`application/json`],[`.jsonld`,`application/ld+json`],[`.mid`,`audio/midi`],[`.midi`,`audio/x-midi`],[`.mjs`,`text/javascript`],[`.mp3`,`audio/mpeg`],[`.mpeg`,`video/mpeg`],[`.mpkg`,`application/vnd.apple.installer+xml`],[`.odp`,`application/vnd.oasis.opendocument.presentation`],[`.ods`,`application/vnd.oasis.opendocument.spreadsheet`],[`.odt`,`application/vnd.oasis.opendocument.text`],[`.oga`,`audio/ogg`],[`.ogv`,`video/ogg`],[`.ogx`,`application/ogg`],[`.opus`,`audio/opus`],[`.otf`,`font/otf`],[`.png`,`image/png`],[`.pdf`,`application/pdf`],[`.php`,`application/x-httpd-php`],[`.ppt`,`application/vnd.ms-powerpoint`],[`.pptx`,`application/vnd.openxmlformats-officedocument.presentationml.presentation`],[`.rar`,`application/vnd.rar`],[`.rtf`,`application/rtf`],[`.sh`,`application/x-sh`],[`.svg`,`image/svg+xml`],[`.swf`,`application/x-shockwave-flash`],[`.tar`,`application/x-tar`],[`.tif`,`image/tiff`],[`.tiff`,`image/tiff`],[`.ts`,`video/mp2t`],[`.ttf`,`font/ttf`],[`.txt`,`text/plain`],[`.vsd`,`application/vnd.visio`],[`.wav`,`audio/wav`],[`.weba`,`audio/webm`],[`.webm`,`video/webm`],[`.webp`,`image/webp`],[`.woff`,`font/woff`],[`.woff2`,`font/woff2`],[`.xhtml`,`application/xhtml+xml`],[`.xls`,`application/vnd.ms-excel`],[`.xlsx`,`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`],[`.xml`,`application/xml`],[`.xul`,`application/vnd.mozilla.xul+xml`],[`.zip`,`application/zip`],[`.3gp`,`video/3gpp`],[`.3g2`,`video/3gpp2`],[`.7z`,`application/x-7z-compressed`]];function S(e){return x.find(t=>t[0]===e)?.[1]||`text/plain`}function C(e,t){let n=[t,t.replaceAll(`\\`,`/`)];for(let t of Object.values(e.environments)){let e=t.moduleGraph;if(!e)continue;let r=new Set,i=t=>{if(!r.has(t)){r.add(t),e.invalidateModule(t);for(let e of t.importers)i(e)}};for(let t of n){let n=e.getModulesByFile(t);if(n)for(let e of n)i(e)}}}async function w(t=5173){let n=await f({server:{middlewareMode:!0},appType:`custom`}),a=p(n.environments.ssr),o=y(n.config),c=n.config.root,l=s(c,o.routes),u=i(s(c,o.islands)).replaceAll(`\\`,`/`),d=m((t,i)=>{function o(e,t){i.statusCode=200,i.setHeader(`Content-Type`,S(e)),i.end(t)}function s(e){i.statusCode=404,i.setHeader(`Content-Type`,S(e)),e===`.html`?i.end(`<!DOCTYPE html><meta charset="utf-8"><h1>404 Not Found</h1>`):i.end()}n.middlewares(t,i,async()=>{let c=t.url??`/`,u=new URL(c,`http://localhost`).pathname.replace(/\/+$/,``)||`/`;try{let{routes:t,runWithRegistry:i}=await a.import(l),d=h(t).find(e=>e.path===u);if(d===void 0){s(`.html`);return}switch(d.type){case`html`:{let{result:e}=i(()=>`<!DOCTYPE html>${r(v(d.render(),`/@id/__x00__virtual:cirro/client`,d.cssPath))}`);o(`.html`,await n.transformIndexHtml(c,e));break}case`css`:{let{registry:t}=i(()=>r(d.render()));o(`.css`,e(t));break}case`file`:{let e=d.render();o(d.ext,e);break}}return}catch(e){i.statusCode=500,i.end(String(e))}})}),g=`${s(c,o.watchDir??`./src`).replaceAll(`\\`,`/`).replace(/\/+$/,``)}/`;n.watcher.on(`change`,e=>{let t=e.replaceAll(`\\`,`/`);t.startsWith(u)||t.startsWith(g)&&(C(n,e),n.ws.send({type:`full-reload`}))}),d.listen(t,()=>{console.log(`cirro dev: http://localhost:${t}`)})}async function T(e){let t=e[0];t===`dev`?await w():t===`build`?await b():(console.error(`usage: cirro <dev|build>`),process.exit(1))}export{T as main};
@@ -0,0 +1,4 @@
1
+ import{AsyncLocalStorage as e}from"node:async_hooks";const t=new e;function n(e,n,r){let i=t.getStore();if(!i)throw Error(`cirro: css() was called outside of a render context`);i.set(e,[n,r])}function r(e){let n=new Map;return{result:t.run(n,e),registry:n}}function i(e,t){let n=t?.selector??`&`,r=t?.atrules??[],i=c({selector:n,atrules:r,properties:e}),a=`${t?.name??`cirro`}-${i.toString(16)}`;return s([...r,n],e,a),a}function a(e){let t=[];return e.layer&&t.push(`@layer ${e.layer}`),e.mediaAtRule&&t.push(`@media (${e.mediaAtRule})`),(e,n)=>i(e,{atrules:t,name:n?.name,selector:n?.selector})}function o(e){let t=`@charset "utf-8";
2
+ @layer base, font, low, main, high;
3
+ `;for(let[n,[r,i]]of e)t+=r.reduceRight((e,t)=>`${t} { ${e} }`,Object.entries(i).map(([e,t])=>`${e.replaceAll(`_`,`-`)}: ${t};`).join(` `)),t+=`
4
+ `;return t}function s(e,t,r){n(r,e.map(e=>e.replaceAll(`&`,`.${r}`)),t)}function c(...e){return l(e.map(e=>JSON.stringify(e)).join(``))}function l(e){let t=5381;for(let n of[...e])t=(t<<5)+t+n.charCodeAt(0)&4294967295;return t>>>0}export{r as i,a as n,o as r,i as t};
package/dist/index.d.ts CHANGED
@@ -462,8 +462,10 @@ type Properties = Partial<{
462
462
  //#endregion
463
463
  //#region src/registry.d.ts
464
464
  type Registry = Map<string, [string[], Partial<Properties>]>;
465
- declare function initCssRegistry(): void;
466
- declare function getCssRegistry(): Registry;
465
+ declare function runWithRegistry<T>(fn: () => T): {
466
+ result: T;
467
+ registry: Registry;
468
+ };
467
469
  //#endregion
468
470
  //#region src/css.d.ts
469
471
  type CssOpt = {
@@ -479,15 +481,17 @@ type GenCssFnOpt = {
479
481
  };
480
482
  declare function genCssFn(opt: GenCssFnOpt): CssFnT;
481
483
  //#endregion
482
- //#region src/router.d.ts
483
- type Params = Record<string, string>;
484
+ //#region src/route.d.ts
485
+ type Params = Record<string, unknown>;
484
486
  type StaticRoute = {
487
+ type: "static";
485
488
  path: string;
486
489
  component: (props: {
487
490
  params: Record<string, never>;
488
491
  }) => ReactElement;
489
492
  };
490
493
  type DynamicRoute<P extends Params = Params> = {
494
+ type: "dynamic";
491
495
  path: (params: P) => string;
492
496
  cssPath: string;
493
497
  getStaticPaths: () => P[];
@@ -495,16 +499,13 @@ type DynamicRoute<P extends Params = Params> = {
495
499
  params: P;
496
500
  }) => ReactElement;
497
501
  };
498
- type AnyRoute = StaticRoute | DynamicRoute<any>;
499
- declare function route<P extends Params>(def: DynamicRoute<P>): DynamicRoute<P>;
500
- declare function route(def: StaticRoute): StaticRoute;
501
- type ResolvedPage = {
502
- url: string;
503
- isCss: boolean;
504
- cssPath: string;
505
- render: () => ReactElement;
502
+ type FileRoute = {
503
+ type: "file";
504
+ path: string;
505
+ component: (props: {
506
+ params: Record<string, never>;
507
+ }) => string;
506
508
  };
507
- declare function expandRoutes(routes: AnyRoute[]): ResolvedPage[];
508
- declare function urlToFilePath(url: string): string;
509
+ type AnyRoute = StaticRoute | DynamicRoute<any> | FileRoute;
509
510
  //#endregion
510
- export { type AnyRoute, type CssOpt, type DynamicRoute, type Params, type Properties, type ResolvedPage, type StaticRoute, css, expandRoutes, genCssFn, getCssRegistry, initCssRegistry, route, urlToFilePath };
511
+ export { type AnyRoute, type CssOpt, type DynamicRoute, type FileRoute, type Params, type Properties, type Registry, type StaticRoute, css, genCssFn, runWithRegistry };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{a as e,c as t,i as n,l as r,n as i,o as a,t as o}from"./router-52EuPj-F.js";export{e as css,o as expandRoutes,a as genCssFn,t as getCssRegistry,r as initCssRegistry,i as route,n as urlToFilePath};
1
+ import{i as e,n as t,t as n}from"./css-L9LEkQky.js";export{n as css,t as genCssFn,e as runWithRegistry};
package/dist/server.d.ts CHANGED
@@ -7,11 +7,14 @@ import { Schema } from "hast-util-sanitize";
7
7
  type IslandRegistry = Record<string, ComponentType<any>>;
8
8
  declare function createIsland<R extends IslandRegistry>(islands: R): <K extends keyof R & string>({
9
9
  name,
10
- props
10
+ props,
11
+ className
11
12
  }: {
12
13
  name: K;
13
14
  props: ComponentProps<R[K]>;
15
+ className?: string;
14
16
  }) => import("react").DetailedReactHTMLElement<{
17
+ className: string | undefined;
15
18
  "data-island": K;
16
19
  "data-props": string;
17
20
  dangerouslySetInnerHTML: {
@@ -34,7 +37,7 @@ interface RenderResult {
34
37
  body: ReactElement;
35
38
  toc: ToC$1[];
36
39
  }
37
- declare function createMarkdown(config?: MarkdownConfig): {
40
+ declare function createMarkdownProcessor(config?: MarkdownConfig): {
38
41
  Markdown: ({
39
42
  source,
40
43
  className
@@ -46,5 +49,6 @@ declare function createMarkdown(config?: MarkdownConfig): {
46
49
  className?: string;
47
50
  }) => RenderResult;
48
51
  };
52
+ declare function markdownToText(md: string): string;
49
53
  //#endregion
50
- export { type MarkdownConfig, type RenderResult, type ToC, createIsland, createMarkdown };
54
+ export { type MarkdownConfig, type RenderResult, type ToC, createIsland, createMarkdownProcessor, markdownToText };
package/dist/server.js CHANGED
@@ -1 +1,2 @@
1
- import{createElement as e}from"react";import{renderToString as t}from"react-dom/server";import n from"rehype-prism";import r,{defaultSchema as i}from"rehype-sanitize";import a from"rehype-stringify";import o from"remark-export-toc";import s from"remark-parse";import c from"remark-rehype";import{unified as l}from"unified";import{jsx as u}from"react/jsx-runtime";function d(n){return function({name:r,props:i}){let a=t(e(n[r],i));return e(`div`,{"data-island":r,"data-props":JSON.stringify(i),dangerouslySetInnerHTML:{__html:a}})}}function f(e={}){let t={prefix:`heading`,startLevel:2,...typeof e.toc==`object`?e.toc:{}},d={...i,clobber:(i.clobber??[]).filter(e=>e!==`id`)},f=e.sanitizeSchema?e.sanitizeSchema(d):d,p=l().use(s).use(e.remarkPlugins??[]).use(e.toc?[[o,t]]:[]).use(c).use(e.rehypePlugins??[]).use(r,f).use(e.highlight?[n]:[]).use(a).freeze();function m(e,t){return u(`div`,{className:t,dangerouslySetInnerHTML:{__html:e}})}function h(e,t){let n=p.processSync(e),r=n.data.toc??[];return{body:m(String(n),t?.className),toc:r}}function g({source:e,className:t}){return h(e,{className:t}).body}return{Markdown:g,render:h}}export{d as createIsland,f as createMarkdown};
1
+ import{createElement as e}from"react";import{renderToString as t}from"react-dom/server";import{fromMarkdown as n}from"mdast-util-from-markdown";import{toString as r}from"mdast-util-to-string";import i from"rehype-prism";import a,{defaultSchema as o}from"rehype-sanitize";import s from"rehype-stringify";import c from"remark-export-toc";import l from"remark-parse";import u from"remark-rehype";import{unified as d}from"unified";import{jsx as f}from"react/jsx-runtime";function p(n){return function({name:r,props:i,className:a}){let o=t(e(n[r],i));return e(`div`,{className:a,"data-island":r,"data-props":JSON.stringify(i),dangerouslySetInnerHTML:{__html:o}})}}function m(e={}){let t={prefix:`heading`,startLevel:2,...typeof e.toc==`object`?e.toc:{}},n={...o,clobber:(o.clobber??[]).filter(e=>e!==`id`)},r=e.sanitizeSchema?e.sanitizeSchema(n):n,p=d().use(l).use(e.remarkPlugins??[]).use(e.toc?[[c,t]]:[]).use(u).use(e.rehypePlugins??[]).use(a,r).use(e.highlight?[i]:[]).use(s).freeze();function m(e,t){return f(`div`,{className:t,dangerouslySetInnerHTML:{__html:e}})}function h(e,t){let n=p.processSync(e),r=n.data.toc??[];return{body:m(String(n),t?.className),toc:r}}function g({source:e,className:t}){return h(e,{className:t}).body}return{Markdown:g,render:h}}function h(e){return n(e).children.map(e=>r(e)).join(`
2
+ `)}export{p as createIsland,m as createMarkdownProcessor,h as markdownToText};
package/dist/vite.js CHANGED
@@ -1,2 +1,2 @@
1
- import{resolve as e}from"node:path";const t=`virtual:cirro/client`,n=`\0${t}`;function r(r){let i=r.islands;return{name:`cirro`,api:{options:r},config(){return{build:{manifest:!0,modulePreload:{polyfill:!1},assetsInlineLimit:0,rollupOptions:{input:{client:t}}}}},configResolved(t){if(i=e(t.root,r.islands),!t.plugins.some(e=>e.name?.startsWith(`vite:react`)))throw Error(`cirro: React プラグインが見つかりません。vite.config の plugins に react()(@vitejs/plugin-react)を cirro() より前に追加してください。`)},resolveId(e){if(e===t)return n},load(e){if(e===n)return[`import { createElement } from "react";`,`import { hydrateRoot } from "react-dom/client";`,`import { islands } from ${JSON.stringify(i)};`,``,`for (const el of document.querySelectorAll("[data-island]")) {`,` const name = el.dataset.island;`,` if (!name || !(name in islands)) continue;`,` const props = el.dataset.props ? JSON.parse(el.dataset.props) : {};`,` hydrateRoot(el, createElement(islands[name], props));`,`}`].join(`
1
+ import{resolve as e}from"node:path";const t=`virtual:cirro/client`,n=`\0${t}`;function r(r){let i=r.islands;return{name:`cirro`,api:{options:r},config(){return{build:{manifest:!0,modulePreload:{polyfill:!1},assetsInlineLimit:0,rollupOptions:{input:{client:t},external:[`node:async_hooks`]}}}},configResolved(t){if(i=e(t.root,r.islands),!t.plugins.some(e=>e.name?.startsWith(`vite:react`)))throw Error(`cirro: React プラグインが見つかりません。vite.config の plugins に react()(@vitejs/plugin-react)を cirro() より前に追加してください。`)},resolveId(e){if(e===t)return n},load(e){if(e===n)return[`import { createElement } from "react";`,`import { hydrateRoot } from "react-dom/client";`,`import { islands } from ${JSON.stringify(i)};`,``,`for (const el of document.querySelectorAll("[data-island]")) {`,` const name = el.dataset.island;`,` if (!name || !(name in islands)) continue;`,` const props = el.dataset.props ? JSON.parse(el.dataset.props) : {};`,` hydrateRoot(el, createElement(islands[name], props));`,`}`].join(`
2
2
  `)}}}export{r as cirro};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cirrojs",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "React islands SSG with strict CSP (no unsafe-inline). Vite-based, MPA-first.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,6 +37,8 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "hast-util-sanitize": "^5.0.2",
40
+ "mdast-util-from-markdown": "^2.0.3",
41
+ "mdast-util-to-string": "^4.0.0",
40
42
  "rehype-prism": "^2.3.3",
41
43
  "rehype-sanitize": "^6.0.0",
42
44
  "rehype-stringify": "^10.0.1",
@@ -1,4 +0,0 @@
1
- const e=new Map;function t(t,n,r){e.set(t,[n,r])}function n(){e.clear()}function r(){return e}function i(e,t){let n=t?.selector??`&`,r=t?.atrules??[],i=c({selector:n,atrules:r,properties:e}),a=`${t?.name??`cirro`}-${i.toString(16)}`;return s([...r,n],e,a),a}function a(e){let t=[];return e.layer&&t.push(`@layer ${e.layer}`),e.mediaAtRule&&t.push(`@media (${e.mediaAtRule})`),(e,n)=>i(e,{atrules:t,name:n?.name,selector:n?.selector})}function o(e){let t=`@charset "utf-8";
2
- @layer base, font, low, main, high;
3
- `;for(let[n,[r,i]]of e)t+=r.reduceRight((e,t)=>`${t} { ${e} }`,Object.entries(i).map(([e,t])=>`${e.replaceAll(`_`,`-`)}: ${t};`).join(` `)),t+=`
4
- `;return t}function s(e,n,r){t(r,e.map(e=>e.replaceAll(`&`,`.${r}`)),n)}function c(...e){return l(e.map(e=>JSON.stringify(e)).join(``))}function l(e){let t=5381;for(let n of[...e])t=(t<<5)+t+n.charCodeAt(0)&4294967295;return t>>>0}function u(e){return e}function d(e){let t=[];for(let n of e)if(`getStaticPaths`in n){for(let e of n.getStaticPaths())t.push({url:n.path(e),isCss:!1,cssPath:n.cssPath,render:()=>n.component({params:e})});t.push({url:n.cssPath,isCss:!0,cssPath:n.cssPath,render:()=>n.component({params:n.getStaticPaths()[0]})})}else t.push({url:n.path,isCss:!1,cssPath:m(n.path,`index.css`),render:()=>n.component({params:{}})}),t.push({url:m(n.path,`index.css`),isCss:!0,cssPath:m(n.path,`index.css`),render:()=>n.component({params:{}})});return t}function f(e){return e===`/`?`index.html`:`${e.replace(/^\/+|\/+$/g,``)}/index.html`}function p(e){return e===`/`?`index.css`:`${e.replace(/^\/+|\/+$/g,``)}`}function m(...e){return e.reduce((e,t)=>e.endsWith(`/`)&&t.startsWith(`/`)?`${e}${t.substring(1)}`:e.endsWith(`/`)||t.startsWith(`/`)?`${e}${t}`:`${e}/${t}`,``)}export{i as a,r as c,f as i,n as l,u as n,a as o,p as r,o as s,d as t};