@prairielearn/preact 1.0.0 → 1.0.2

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 ADDED
@@ -0,0 +1,20 @@
1
+ # @prairielearn/preact
2
+
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - c72a4b8: Upgrade dependencies
8
+ - Updated dependencies [c72a4b8]
9
+ - @prairielearn/browser-utils@2.2.14
10
+ - @prairielearn/compiled-assets@3.2.7
11
+ - @prairielearn/error@2.0.20
12
+ - @prairielearn/html@4.0.20
13
+ - @prairielearn/preact-cjs@1.1.4
14
+ - @prairielearn/utils@2.0.1
15
+
16
+ ## 1.0.1
17
+
18
+ ### Patch Changes
19
+
20
+ - 8c03925: Use pretty rendering in dev mode in `renderHtmlDocument(...)`
package/dist/server.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "@prairielearn/preact-cjs/jsx-runtime";
2
2
  import clsx from 'clsx';
3
3
  import { isFragment, isValidElement } from 'preact/compat';
4
- import { render } from 'preact-render-to-string/jsx';
5
4
  import superjson from 'superjson';
6
5
  import { compiledScriptPath, compiledScriptPreloadPaths } from '@prairielearn/compiled-assets';
7
6
  import { AugmentedError } from '@prairielearn/error';
@@ -33,7 +32,7 @@ function escapeJsonForHtml(value) {
33
32
  * @returns An HTML string containing the rendered content.
34
33
  */
35
34
  export function renderHtmlDocument(content) {
36
- return `<!doctype html>\n${render(content, {}, { pretty: true, jsx: false })}`;
35
+ return `<!doctype html>\n${renderHtml(content)}`;
37
36
  }
38
37
  /**
39
38
  * A component that renders a Preact component for client-side hydration.
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.tsx"],"names":[],"mappings":"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","sourcesContent":["import clsx from 'clsx';\nimport { isFragment, isValidElement } from 'preact/compat';\nimport { render } from 'preact-render-to-string/jsx';\nimport superjson from 'superjson';\n\nimport { compiledScriptPath, compiledScriptPreloadPaths } from '@prairielearn/compiled-assets';\nimport { AugmentedError } from '@prairielearn/error';\nimport { type HtmlSafeString, html } from '@prairielearn/html';\nimport { type ComponentChildren, Fragment, type VNode } from '@prairielearn/preact-cjs';\n\nimport { renderHtml } from './index.js';\n\n// Based on https://pkg.go.dev/encoding/json#HTMLEscape\nconst ENCODE_HTML_RULES: Record<string, string> = {\n '&': '\\\\u0026',\n '>': '\\\\u003e',\n '<': '\\\\u003c',\n '\\u2028': '\\\\u2028',\n '\\u2029': '\\\\u2029',\n};\nconst MATCH_HTML = /[&><\\u2028\\u2029]/g;\n\n/**\n * Escape a value for use in a JSON string that will be rendered in HTML.\n *\n * @param value - The value to escape.\n * @returns A JSON string with HTML-sensitive characters escaped.\n */\nfunction escapeJsonForHtml(value: any): string {\n return superjson.stringify(value).replaceAll(MATCH_HTML, (c) => ENCODE_HTML_RULES[c] || c);\n}\n\n/**\n * Render an entire Preact page as an HTML document.\n *\n * @param content - A Preact VNode to render to HTML.\n * @returns An HTML string containing the rendered content.\n */\nexport function renderHtmlDocument(content: VNode) {\n return `<!doctype html>\\n${render(content, {}, { pretty: true, jsx: false })}`;\n}\n\ninterface HydrateProps {\n /** The component to hydrate */\n children: ComponentChildren;\n /** Optional override for the component's name or displayName */\n nameOverride?: string;\n /** Whether to apply full height styles. */\n fullHeight?: boolean;\n}\n\n/**\n * A component that renders a Preact component for client-side hydration.\n * All interactive components will need to be hydrated.\n * This component is intended to be used within a non-interactive Preact component\n * that will be rendered without hydration through `renderHtml`.\n */\nexport function Hydrate({ children, nameOverride, fullHeight = false }: HydrateProps): VNode {\n if (!isValidElement(children)) {\n throw new Error('<Hydrate> expects a single Preact component as its child');\n }\n\n if (isFragment(children)) {\n throw new Error('<Hydrate> does not support fragments');\n }\n\n const content = children as VNode;\n const { type: Component, props } = content;\n if (typeof Component !== 'function') {\n throw new Error('<Hydrate> expects a Preact component');\n }\n\n // Note that we don't use `Component.name` here because it can be minified or mangled.\n const componentName = nameOverride ?? Component.displayName;\n if (!componentName) {\n // This is only defined in development, not in production when the function name is minified.\n const componentDevName = Component.name || 'UnknownComponent';\n throw new AugmentedError(\n '<Hydrate> expects a component to have a displayName or nameOverride.',\n {\n info: html`\n <div>\n <p>Make sure to add a displayName to the component:</p>\n <pre><code>export const ${componentDevName} = ...;\n// Add this line:\n${componentDevName}.displayName = '${componentDevName}';</code></pre>\n </div>\n `,\n },\n );\n }\n\n const scriptPath = `esm-bundles/hydrated-components/${componentName}.ts`;\n let compiledScriptSrc = '';\n try {\n compiledScriptSrc = compiledScriptPath(scriptPath);\n } catch (error) {\n throw new AugmentedError(`Could not find script for component \"${componentName}\".`, {\n info: html`\n <div>\n Make sure you create a script at\n <code>esm-bundles/hydrated-components/${componentName}.ts</code> registering the\n component:\n <pre><code>import { registerHydratedComponent } from '@prairielearn/preact/hydrated-component';\n\nimport { ${componentName} } from './path/to/component.js';\n\nregisterHydratedComponent(${componentName});</code></pre>\n </div>\n `,\n cause: error,\n });\n }\n const scriptPreloads = compiledScriptPreloadPaths(scriptPath);\n return (\n <Fragment>\n <script type=\"module\" src={compiledScriptSrc} />\n {scriptPreloads.map((preloadPath) => (\n <link key={preloadPath} rel=\"modulepreload\" href={preloadPath} />\n ))}\n <div\n data-component={componentName}\n class={clsx('js-hydrated-component', { 'h-100': fullHeight })}\n >\n <script\n type=\"application/json\"\n // eslint-disable-next-line @eslint-react/dom/no-dangerously-set-innerhtml\n dangerouslySetInnerHTML={{\n __html: escapeJsonForHtml(props),\n }}\n data-component-props\n />\n <div class={fullHeight ? 'h-100' : ''} data-component-root>\n <Component {...props} />\n </div>\n </div>\n </Fragment>\n );\n}\n\n/**\n * Renders a Preact component for client-side hydration and returns an HTML-safe string.\n * This function is intended to be used within a tagged template literal, e.g. html`...`.\n *\n * @param content - A Preact VNode to render to HTML.\n * @returns An `HtmlSafeString` containing the rendered HTML.\n */\nexport function hydrateHtml<T>(content: VNode<T>): HtmlSafeString {\n // Useful for adding Preact components to existing tagged-template pages.\n return renderHtml(<Hydrate>{content}</Hydrate>);\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.tsx"],"names":[],"mappings":"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","sourcesContent":["import clsx from 'clsx';\nimport { isFragment, isValidElement } from 'preact/compat';\nimport superjson from 'superjson';\n\nimport { compiledScriptPath, compiledScriptPreloadPaths } from '@prairielearn/compiled-assets';\nimport { AugmentedError } from '@prairielearn/error';\nimport { type HtmlSafeString, html } from '@prairielearn/html';\nimport { type ComponentChildren, Fragment, type VNode } from '@prairielearn/preact-cjs';\n\nimport { renderHtml } from './index.js';\n\n// Based on https://pkg.go.dev/encoding/json#HTMLEscape\nconst ENCODE_HTML_RULES: Record<string, string> = {\n '&': '\\\\u0026',\n '>': '\\\\u003e',\n '<': '\\\\u003c',\n '\\u2028': '\\\\u2028',\n '\\u2029': '\\\\u2029',\n};\nconst MATCH_HTML = /[&><\\u2028\\u2029]/g;\n\n/**\n * Escape a value for use in a JSON string that will be rendered in HTML.\n *\n * @param value - The value to escape.\n * @returns A JSON string with HTML-sensitive characters escaped.\n */\nfunction escapeJsonForHtml(value: any): string {\n return superjson.stringify(value).replaceAll(MATCH_HTML, (c) => ENCODE_HTML_RULES[c] || c);\n}\n\n/**\n * Render an entire Preact page as an HTML document.\n *\n * @param content - A Preact VNode to render to HTML.\n * @returns An HTML string containing the rendered content.\n */\nexport function renderHtmlDocument(content: VNode) {\n return `<!doctype html>\\n${renderHtml(content)}`;\n}\n\ninterface HydrateProps {\n /** The component to hydrate */\n children: ComponentChildren;\n /** Optional override for the component's name or displayName */\n nameOverride?: string;\n /** Whether to apply full height styles. */\n fullHeight?: boolean;\n}\n\n/**\n * A component that renders a Preact component for client-side hydration.\n * All interactive components will need to be hydrated.\n * This component is intended to be used within a non-interactive Preact component\n * that will be rendered without hydration through `renderHtml`.\n */\nexport function Hydrate({ children, nameOverride, fullHeight = false }: HydrateProps): VNode {\n if (!isValidElement(children)) {\n throw new Error('<Hydrate> expects a single Preact component as its child');\n }\n\n if (isFragment(children)) {\n throw new Error('<Hydrate> does not support fragments');\n }\n\n const content = children as VNode;\n const { type: Component, props } = content;\n if (typeof Component !== 'function') {\n throw new Error('<Hydrate> expects a Preact component');\n }\n\n // Note that we don't use `Component.name` here because it can be minified or mangled.\n const componentName = nameOverride ?? Component.displayName;\n if (!componentName) {\n // This is only defined in development, not in production when the function name is minified.\n const componentDevName = Component.name || 'UnknownComponent';\n throw new AugmentedError(\n '<Hydrate> expects a component to have a displayName or nameOverride.',\n {\n info: html`\n <div>\n <p>Make sure to add a displayName to the component:</p>\n <pre><code>export const ${componentDevName} = ...;\n// Add this line:\n${componentDevName}.displayName = '${componentDevName}';</code></pre>\n </div>\n `,\n },\n );\n }\n\n const scriptPath = `esm-bundles/hydrated-components/${componentName}.ts`;\n let compiledScriptSrc = '';\n try {\n compiledScriptSrc = compiledScriptPath(scriptPath);\n } catch (error) {\n throw new AugmentedError(`Could not find script for component \"${componentName}\".`, {\n info: html`\n <div>\n Make sure you create a script at\n <code>esm-bundles/hydrated-components/${componentName}.ts</code> registering the\n component:\n <pre><code>import { registerHydratedComponent } from '@prairielearn/preact/hydrated-component';\n\nimport { ${componentName} } from './path/to/component.js';\n\nregisterHydratedComponent(${componentName});</code></pre>\n </div>\n `,\n cause: error,\n });\n }\n const scriptPreloads = compiledScriptPreloadPaths(scriptPath);\n return (\n <Fragment>\n <script type=\"module\" src={compiledScriptSrc} />\n {scriptPreloads.map((preloadPath) => (\n <link key={preloadPath} rel=\"modulepreload\" href={preloadPath} />\n ))}\n <div\n data-component={componentName}\n class={clsx('js-hydrated-component', { 'h-100': fullHeight })}\n >\n <script\n type=\"application/json\"\n // eslint-disable-next-line @eslint-react/dom/no-dangerously-set-innerhtml\n dangerouslySetInnerHTML={{\n __html: escapeJsonForHtml(props),\n }}\n data-component-props\n />\n <div class={fullHeight ? 'h-100' : ''} data-component-root>\n <Component {...props} />\n </div>\n </div>\n </Fragment>\n );\n}\n\n/**\n * Renders a Preact component for client-side hydration and returns an HTML-safe string.\n * This function is intended to be used within a tagged template literal, e.g. html`...`.\n *\n * @param content - A Preact VNode to render to HTML.\n * @returns An `HtmlSafeString` containing the rendered HTML.\n */\nexport function hydrateHtml<T>(content: VNode<T>): HtmlSafeString {\n // Useful for adding Preact components to existing tagged-template pages.\n return renderHtml(<Hydrate>{content}</Hydrate>);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prairielearn/preact",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,21 +17,21 @@
17
17
  "dev": "tsc --watch --preserveWatchOutput"
18
18
  },
19
19
  "dependencies": {
20
- "@prairielearn/browser-utils": "^2.2.13",
21
- "@prairielearn/compiled-assets": "^3.2.6",
22
- "@prairielearn/error": "^2.0.19",
23
- "@prairielearn/html": "^4.0.19",
24
- "@prairielearn/preact-cjs": "^1.1.3",
25
- "@prairielearn/utils": "^2.0.0",
20
+ "@prairielearn/browser-utils": "^2.2.14",
21
+ "@prairielearn/compiled-assets": "^3.2.7",
22
+ "@prairielearn/error": "^2.0.20",
23
+ "@prairielearn/html": "^4.0.20",
24
+ "@prairielearn/preact-cjs": "^1.1.4",
25
+ "@prairielearn/utils": "^2.0.1",
26
26
  "clsx": "^2.1.1",
27
27
  "preact": "^10.27.0",
28
- "preact-render-to-string": "^6.6.1",
28
+ "preact-render-to-string": "^6.6.2",
29
29
  "selector-observer": "^2.1.6",
30
30
  "superjson": "^2.2.2"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@prairielearn/tsconfig": "^0.0.0",
34
- "@types/node": "^22.18.0",
35
- "typescript": "^5.9.2"
34
+ "@types/node": "^22.18.8",
35
+ "typescript": "^5.9.3"
36
36
  }
37
37
  }
package/src/server.tsx CHANGED
@@ -1,6 +1,5 @@
1
1
  import clsx from 'clsx';
2
2
  import { isFragment, isValidElement } from 'preact/compat';
3
- import { render } from 'preact-render-to-string/jsx';
4
3
  import superjson from 'superjson';
5
4
 
6
5
  import { compiledScriptPath, compiledScriptPreloadPaths } from '@prairielearn/compiled-assets';
@@ -37,7 +36,7 @@ function escapeJsonForHtml(value: any): string {
37
36
  * @returns An HTML string containing the rendered content.
38
37
  */
39
38
  export function renderHtmlDocument(content: VNode) {
40
- return `<!doctype html>\n${render(content, {}, { pretty: true, jsx: false })}`;
39
+ return `<!doctype html>\n${renderHtml(content)}`;
41
40
  }
42
41
 
43
42
  interface HydrateProps {