@rocket/js 0.2.0 → 0.3.0
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-types/exports/adapters/cloudflare.d.ts +2 -0
- package/dist-types/exports/adapters/cloudflare.d.ts.map +1 -0
- package/dist-types/exports/ssr.d.ts +1 -1
- package/dist-types/exports/types/rocket.d.ts +11 -0
- package/dist-types/exports/types/rocket.d.ts.map +1 -1
- package/dist-types/exports/types.d.ts +1 -1
- package/dist-types/exports/types.d.ts.map +1 -1
- package/dist-types/src/PageData.d.ts +9 -0
- package/dist-types/src/PageData.d.ts.map +1 -1
- package/dist-types/src/RocketCodeBlock.d.ts.map +1 -1
- package/dist-types/src/RocketJsDemo.d.ts.map +1 -1
- package/dist-types/src/adapters/cloudflare.d.ts +27 -0
- package/dist-types/src/adapters/cloudflare.d.ts.map +1 -0
- package/dist-types/src/adapters/netlify.d.ts.map +1 -1
- package/dist-types/src/adapters/redirects.d.ts +14 -0
- package/dist-types/src/adapters/redirects.d.ts.map +1 -0
- package/dist-types/src/icons.d.ts +27 -0
- package/dist-types/src/icons.d.ts.map +1 -1
- package/dist-types/src/layouts/atlas/atlasBlogLayout.d.ts.map +1 -1
- package/dist-types/src/layouts/atlas/atlasDocLayout.d.ts.map +1 -1
- package/dist-types/src/layouts/atlas/atlasHeroLayout.d.ts.map +1 -1
- package/dist-types/src/layouts/atlas/atlasNotFoundLayout.d.ts.map +1 -1
- package/dist-types/src/layouts/layout-helper.d.ts.map +1 -1
- package/dist-types/src/markdownHook.d.ts.map +1 -1
- package/dist-types/src/menus/MainMenu.d.ts.map +1 -1
- package/dist-types/src/menus/RocketMenu.d.ts.map +1 -1
- package/dist-types/src/menus/RocketToc.d.ts.map +1 -1
- package/dist-types/src/menus/pageNavigation.d.ts.map +1 -1
- package/dist-types/src/prefer-project-packages-plugin.d.ts +9 -0
- package/dist-types/src/prefer-project-packages-plugin.d.ts.map +1 -0
- package/dist-types/src/project-package-resolution.d.ts +8 -0
- package/dist-types/src/project-package-resolution.d.ts.map +1 -0
- package/dist-types/src/publicAssets.d.ts.map +1 -1
- package/dist-types/src/resolve.d.ts.map +1 -1
- package/dist-types/src/ssr.d.ts +3 -0
- package/dist-types/src/ssr.d.ts.map +1 -1
- package/dist-types/src/transform.d.ts.map +1 -1
- package/exports/adapters/cloudflare.js +1 -0
- package/exports/ssr.js +1 -1
- package/exports/types/rocket.ts +17 -4
- package/exports/types.ts +1 -0
- package/package.json +41 -26
- package/src/PageData.js +15 -0
- package/src/RocketCodeBlock.js +11 -9
- package/src/RocketJsDemo.js +8 -6
- package/src/adapters/cloudflare.js +522 -0
- package/src/adapters/netlify.js +2 -24
- package/src/adapters/redirects.js +31 -0
- package/src/cli/RocketBuild.js +5 -2
- package/src/config.js +1 -1
- package/src/icons.js +143 -1
- package/src/layouts/atlas/atlasBlogLayout.js +45 -31
- package/src/layouts/atlas/atlasDocLayout.js +22 -16
- package/src/layouts/atlas/atlasHeroLayout.js +39 -31
- package/src/layouts/atlas/atlasNotFoundLayout.js +5 -3
- package/src/layouts/layout-helper.js +38 -26
- package/src/main.js +17 -0
- package/src/markdownCompiler.js +5 -1
- package/src/menus/MainMenu.js +17 -13
- package/src/menus/RocketMenu.js +25 -19
- package/src/menus/RocketToc.js +7 -5
- package/src/menus/pageNavigation.js +24 -10
- package/src/prefer-project-packages-plugin.js +31 -0
- package/src/project-package-resolution.js +36 -0
- package/src/publicAssets.js +9 -2
- package/src/resolve.js +32 -2
- package/src/ssr.js +3 -0
- package/src/transform.js +15 -9
- package/src/wds-plugin.js +2 -1
package/src/menus/RocketMenu.js
CHANGED
|
@@ -47,25 +47,31 @@ export class RocketMenu extends LitElement {
|
|
|
47
47
|
|
|
48
48
|
return html`
|
|
49
49
|
<li class=${classMap(itemClasses)}>
|
|
50
|
-
${
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
50
|
+
${
|
|
51
|
+
page.menuNoLink
|
|
52
|
+
? html`<span class=${classMap(classes)}>${title}</span>`
|
|
53
|
+
: html`<a
|
|
54
|
+
href=${ifDefined(page.url)}
|
|
55
|
+
class=${classMap(classes)}
|
|
56
|
+
aria-current=${ifDefined(isCurrent ? 'page' : undefined)}
|
|
57
|
+
>${
|
|
58
|
+
page.iconName
|
|
59
|
+
? html`<rocket-icon
|
|
60
|
+
class="nav-icon"
|
|
61
|
+
name=${page.iconName}
|
|
62
|
+
aria-hidden="true"
|
|
63
|
+
></rocket-icon>`
|
|
64
|
+
: ''
|
|
65
|
+
}<span class="nav-text">${title}</span></a
|
|
66
|
+
>`
|
|
67
|
+
}
|
|
68
|
+
${
|
|
69
|
+
page.children.length > 0
|
|
70
|
+
? html`<ul>
|
|
71
|
+
${page.children.map(child => this.list(child, depth + 1))}
|
|
72
|
+
</ul>`
|
|
73
|
+
: ''
|
|
74
|
+
}
|
|
69
75
|
</li>
|
|
70
76
|
`;
|
|
71
77
|
}
|
package/src/menus/RocketToc.js
CHANGED
|
@@ -68,11 +68,13 @@ export class RocketToc extends LitElement {
|
|
|
68
68
|
>
|
|
69
69
|
${headline.text}
|
|
70
70
|
</a>
|
|
71
|
-
${
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
${
|
|
72
|
+
headline.children.length > 0
|
|
73
|
+
? html`<ol>
|
|
74
|
+
${headline.children.map(child => this.list(child, depth + 1))}
|
|
75
|
+
</ol>`
|
|
76
|
+
: html``
|
|
77
|
+
}
|
|
76
78
|
</li>
|
|
77
79
|
`;
|
|
78
80
|
}
|
|
@@ -50,20 +50,34 @@ export function renderPageNavigationCard(page, direction) {
|
|
|
50
50
|
const isNext = direction === 'next';
|
|
51
51
|
const label = isNext ? 'Next Page' : 'Previous Page';
|
|
52
52
|
const icon = html`<span class="page-card-icon" aria-hidden="true">
|
|
53
|
-
${
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
${
|
|
54
|
+
isNext
|
|
55
|
+
? html`<svg
|
|
56
|
+
class="page-card-arrow"
|
|
57
|
+
viewBox="0 0 36 16"
|
|
58
|
+
focusable="false"
|
|
59
|
+
aria-hidden="true"
|
|
60
|
+
>
|
|
61
|
+
<path d="M5 8h25m-7-6 7 6-7 6" />
|
|
62
|
+
</svg>`
|
|
63
|
+
: html`<svg
|
|
64
|
+
class="page-card-arrow"
|
|
65
|
+
viewBox="0 0 36 16"
|
|
66
|
+
focusable="false"
|
|
67
|
+
aria-hidden="true"
|
|
68
|
+
>
|
|
69
|
+
<path d="M31 8H6m7-6-7 6 7 6" />
|
|
70
|
+
</svg>`
|
|
71
|
+
}
|
|
60
72
|
</span>`;
|
|
61
73
|
const text = html`<span class="page-card-text">
|
|
62
74
|
<span class="page-card-label">${label}</span>
|
|
63
75
|
<strong class="page-card-title">${page.linkText}</strong>
|
|
64
|
-
${
|
|
65
|
-
|
|
66
|
-
|
|
76
|
+
${
|
|
77
|
+
page.sectionLabel
|
|
78
|
+
? html`<span class="page-card-section">${page.sectionLabel}</span>`
|
|
79
|
+
: nothing
|
|
80
|
+
}
|
|
67
81
|
</span>`;
|
|
68
82
|
|
|
69
83
|
return html`<a
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { resolveProjectBrowserPackage } from './project-package-resolution.js';
|
|
2
|
+
import { resolve } from './resolve.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Keeps browser packages shared between a Site Author project and a linked Rocket checkout.
|
|
6
|
+
* Packages absent from the project are left to normal Node resolution, which falls back to
|
|
7
|
+
* Rocket's dependency.
|
|
8
|
+
*
|
|
9
|
+
* @returns {import('@web/dev-server-core').Plugin}
|
|
10
|
+
*/
|
|
11
|
+
export function preferProjectPackagesPlugin() {
|
|
12
|
+
/** @type {Map<string, string | undefined>} */
|
|
13
|
+
const resolvedImports = new Map();
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
name: 'rocket-prefer-project-packages',
|
|
17
|
+
resolveImport({ source }) {
|
|
18
|
+
if (resolvedImports.has(source)) {
|
|
19
|
+
return resolvedImports.get(source);
|
|
20
|
+
}
|
|
21
|
+
let resolved;
|
|
22
|
+
try {
|
|
23
|
+
resolved = resolveProjectBrowserPackage(source) ? resolve(source, import.meta) : undefined;
|
|
24
|
+
} catch {
|
|
25
|
+
resolved = undefined;
|
|
26
|
+
}
|
|
27
|
+
resolvedImports.set(source, resolved);
|
|
28
|
+
return resolved;
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { moduleResolve } from 'import-meta-resolve';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const browserImportConditions = new Set(['browser', 'import', 'module']);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a bare package import from the Site Author project using browser ESM conditions.
|
|
9
|
+
* Built-in modules and packages absent from the project are left to another resolver.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} specifier
|
|
12
|
+
*/
|
|
13
|
+
export function resolveProjectBrowserPackage(specifier) {
|
|
14
|
+
if (!isPackageSpecifier(specifier)) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const projectParent = pathToFileURL(path.join(process.cwd(), 'package.json'));
|
|
19
|
+
const resolved = moduleResolve(specifier, projectParent, browserImportConditions, false);
|
|
20
|
+
return resolved.protocol === 'file:' ? resolved.href : undefined;
|
|
21
|
+
} catch {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} specifier
|
|
28
|
+
*/
|
|
29
|
+
function isPackageSpecifier(specifier) {
|
|
30
|
+
return (
|
|
31
|
+
!specifier.startsWith('.') &&
|
|
32
|
+
!specifier.startsWith('/') &&
|
|
33
|
+
!specifier.startsWith('#') &&
|
|
34
|
+
!URL.canParse(specifier)
|
|
35
|
+
);
|
|
36
|
+
}
|
package/src/publicAssets.js
CHANGED
|
@@ -5,6 +5,12 @@ import { paginatedArchivePaths } from './page-pagination.js';
|
|
|
5
5
|
import { normalizeDocumentPath, standaloneDemoPaths } from './standalone-demo-url.js';
|
|
6
6
|
import { needsDefaultSocialPreviewImage, publicSocialPreviewPages } from './socialPreviewImages.js';
|
|
7
7
|
|
|
8
|
+
/** Adapters that write `_redirects` into the build output, by adapter name. */
|
|
9
|
+
const REDIRECTS_FILE_HOSTS = new Map([
|
|
10
|
+
['netlify', 'Netlify'],
|
|
11
|
+
['cloudflare', 'Cloudflare'],
|
|
12
|
+
]);
|
|
13
|
+
|
|
8
14
|
export const PUBLIC_ASSETS_DIR = 'public';
|
|
9
15
|
|
|
10
16
|
/**
|
|
@@ -237,8 +243,9 @@ function generatedOutputClaims({ pages, generatedPages, config, emitRedirectFall
|
|
|
237
243
|
if (config.siteDiscoverability?.robots === true) {
|
|
238
244
|
claims.set('/robots.txt', 'generated Robots File');
|
|
239
245
|
}
|
|
240
|
-
|
|
241
|
-
|
|
246
|
+
const redirectsFileHost = REDIRECTS_FILE_HOSTS.get(config.adapter?.name ?? '');
|
|
247
|
+
if (redirectsFileHost && config.urlLifecycle?.redirects?.length) {
|
|
248
|
+
claims.set('/_redirects', `${redirectsFileHost} Redirect output`);
|
|
242
249
|
}
|
|
243
250
|
|
|
244
251
|
return claims;
|
package/src/resolve.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
|
+
import { resolveProjectBrowserPackage } from './project-package-resolution.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @param {string} url
|
|
@@ -9,7 +10,36 @@ import { fileURLToPath } from 'url';
|
|
|
9
10
|
export function resolve(url, meta) {
|
|
10
11
|
// get current directory
|
|
11
12
|
const outputFilePath = process.cwd();
|
|
12
|
-
const resolvedPath = meta.resolve(url);
|
|
13
|
+
const resolvedPath = resolveProjectBrowserPackage(url) ?? meta.resolve(url);
|
|
13
14
|
const rel = path.relative(outputFilePath, fileURLToPath(resolvedPath));
|
|
14
|
-
|
|
15
|
+
if (process.env.ENVIRONMENT === 'BUILD') {
|
|
16
|
+
return `/../${toBrowserPath(rel)}`;
|
|
17
|
+
}
|
|
18
|
+
return developmentBrowserPath(rel);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Web Dev Server represents files outside its root with a path that records how many parent
|
|
23
|
+
* directories to traverse. Browsers normalize ordinary `/../` segments before making a request,
|
|
24
|
+
* so linked packages need this explicit form.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} relativePath
|
|
27
|
+
*/
|
|
28
|
+
function developmentBrowserPath(relativePath) {
|
|
29
|
+
const parts = relativePath.split(path.sep);
|
|
30
|
+
let outsideRootDepth = 0;
|
|
31
|
+
while (parts[outsideRootDepth] === '..') {
|
|
32
|
+
outsideRootDepth += 1;
|
|
33
|
+
}
|
|
34
|
+
const browserPath = parts.slice(outsideRootDepth).join('/');
|
|
35
|
+
return outsideRootDepth
|
|
36
|
+
? `/__wds-outside-root__/${outsideRootDepth}/${browserPath}`
|
|
37
|
+
: `/${browserPath}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {string} filePath
|
|
42
|
+
*/
|
|
43
|
+
function toBrowserPath(filePath) {
|
|
44
|
+
return filePath.split(path.sep).join('/');
|
|
15
45
|
}
|
package/src/ssr.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/** Runs on: imported-js */
|
|
2
2
|
import { render } from '@lit-labs/ssr';
|
|
3
3
|
import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
|
|
4
|
+
import { html } from 'lit';
|
|
5
|
+
|
|
6
|
+
export { html, render };
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* @param {string | import('lit').TemplateResult} template
|
package/src/transform.js
CHANGED
|
@@ -90,10 +90,11 @@ export async function mdToJsSingleDemo(md, demo) {
|
|
|
90
90
|
|
|
91
91
|
const code = /** @type {{client: string; server: string}} */ (result.data.code);
|
|
92
92
|
|
|
93
|
-
const
|
|
93
|
+
const runtimeImport = hasTopLevelHtmlBinding(code.server)
|
|
94
|
+
? "import { render } from '@rocket/js/ssr.js';"
|
|
95
|
+
: "import { html, render } from '@rocket/js/ssr.js';";
|
|
94
96
|
const moduleCode = `
|
|
95
|
-
|
|
96
|
-
${litImport}
|
|
97
|
+
${runtimeImport}
|
|
97
98
|
${code.server}
|
|
98
99
|
export function contentFn(data, layout) {
|
|
99
100
|
data._clientCode = \`${code.client
|
|
@@ -117,12 +118,11 @@ export function contentFn(data, layout) {
|
|
|
117
118
|
*/
|
|
118
119
|
async function makeJsFile(serverCode, clientCode, markdown, headlines) {
|
|
119
120
|
const normalizedServerCode = normalizeLayoutExportBindings(serverCode);
|
|
120
|
-
const
|
|
121
|
-
? ''
|
|
122
|
-
: "import { html } from '
|
|
121
|
+
const runtimeImport = hasTopLevelHtmlBinding(normalizedServerCode)
|
|
122
|
+
? "import { render } from '@rocket/js/ssr.js';"
|
|
123
|
+
: "import { html, render } from '@rocket/js/ssr.js';";
|
|
123
124
|
return `
|
|
124
|
-
|
|
125
|
-
${litImport}
|
|
125
|
+
${runtimeImport}
|
|
126
126
|
${normalizedServerCode}
|
|
127
127
|
export function contentFn(data, defaultLayout) {
|
|
128
128
|
let renderLayout = defaultLayout;
|
|
@@ -412,7 +412,13 @@ export function isDemoCodeNode(node) {
|
|
|
412
412
|
*/
|
|
413
413
|
function demoExportName(code) {
|
|
414
414
|
const [, moduleExports] = parseExports(code);
|
|
415
|
-
const
|
|
415
|
+
const first = moduleExports[0];
|
|
416
|
+
const name =
|
|
417
|
+
first?.type === 'direct'
|
|
418
|
+
? first.localName || first.name
|
|
419
|
+
: first?.type === 'reexport'
|
|
420
|
+
? first.name
|
|
421
|
+
: undefined;
|
|
416
422
|
if (!name) {
|
|
417
423
|
throw new Error(
|
|
418
424
|
'A ```js demo code block must export the demo function, ' +
|
package/src/wds-plugin.js
CHANGED
|
@@ -129,7 +129,8 @@ export default (include, exclude, resolverPort, options = {}) => {
|
|
|
129
129
|
type: rocketIconRuntime.type,
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
|
-
const iconAsset =
|
|
132
|
+
const iconAsset =
|
|
133
|
+
iconAssetStore.get(context.path) ?? (await iconAssetStore.getWebAwesomeIcon(context.path));
|
|
133
134
|
if (iconAsset) {
|
|
134
135
|
return {
|
|
135
136
|
body: iconAsset.svg,
|