forgebook 0.2.0 → 0.3.1
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/README.md +113 -5
- package/dist/bin/forgebook/agentLoopCommands.mjs +3 -0
- package/dist/bin/forgebook/agentText.d.ts +2 -2
- package/dist/bin/forgebook/agentText.js +15 -13
- package/dist/bin/forgebook/agents.md +21 -6
- package/dist/bin/forgebook/mcpTools.js +1 -1
- package/dist/bin/forgebook/newStoriesFile.js +7 -2
- package/dist/bin/forgebook-docs/collectDocs.js +1 -1
- package/dist/src/argsProps.d.ts +32 -0
- package/dist/src/argsProps.js +69 -0
- package/dist/src/catalogue.d.ts +48 -5
- package/dist/src/catalogue.js +47 -8
- package/dist/src/frame/mountFrame.js +26 -7
- package/dist/src/frame/touchCaret.d.ts +43 -0
- package/dist/src/frame/touchCaret.js +195 -0
- package/dist/src/frame/touchEvents.d.ts +3 -2
- package/dist/src/frame/touchEvents.js +17 -18
- package/dist/src/frame/touchLayer.js +48 -7
- package/dist/src/propGroups.d.ts +66 -3
- package/dist/src/propGroups.js +67 -13
- package/dist/src/shell/ApiReference.d.ts +9 -4
- package/dist/src/shell/ApiReference.js +47 -39
- package/dist/src/shell/AudienceSections.js +1 -1
- package/dist/src/shell/ComponentPage.d.ts +5 -2
- package/dist/src/shell/ComponentPage.js +4 -18
- package/dist/src/shell/DocBlocks.js +1 -1
- package/dist/src/shell/PropRows.d.ts +42 -0
- package/dist/src/shell/PropRows.js +60 -0
- package/dist/src/shell/PropsTab.d.ts +14 -10
- package/dist/src/shell/PropsTab.js +18 -58
- package/dist/src/shell/RequiredFirstSwitch.d.ts +16 -0
- package/dist/src/shell/RequiredFirstSwitch.js +8 -0
- package/dist/src/shell/Stage.js +11 -23
- package/dist/src/shell/StoryCoverage.js +4 -1
- package/dist/src/shell/docPage.css +6 -0
- package/dist/src/shell/dockTabs.d.ts +7 -5
- package/dist/src/shell/dockTabs.js +4 -4
- package/dist/src/shell/reportedPanel.d.ts +12 -0
- package/dist/src/shell/reportedPanel.js +19 -0
- package/dist/src/shell/shell.css +56 -1
- package/dist/src/shell/strings.d.ts +2 -0
- package/dist/src/shell/strings.js +2 -0
- package/dist/src/shell/usePanelDocs.d.ts +11 -0
- package/dist/src/shell/usePanelDocs.js +29 -0
- package/dist/src/shell/useRequiredFirst.d.ts +27 -0
- package/dist/src/shell/useRequiredFirst.js +67 -0
- package/dist/src/storyCheck.d.ts +2 -0
- package/dist/src/storyCheck.js +2 -1
- package/dist/src/storyGlobals.js +2 -1
- package/dist/src/storyTree.d.ts +11 -1
- package/dist/src/storyTree.js +3 -1
- package/dist/src/viewState.d.ts +7 -0
- package/dist/src/viewState.js +13 -0
- package/dist/src/vite/agent.types.d.ts +12 -0
- package/dist/src/vite/agentApi.js +6 -1
- package/dist/src/vite/agentRoutes.js +18 -4
- package/dist/src/vite/builtTexts.d.ts +2 -2
- package/dist/src/vite/builtTexts.js +7 -6
- package/dist/src/vite/configFile.d.ts +3 -2
- package/dist/src/vite/configFile.js +63 -14
- package/dist/src/vite/docPagesModule.d.ts +10 -7
- package/dist/src/vite/docPagesModule.js +14 -11
- package/dist/src/vite/docsExtractor.d.ts +6 -0
- package/dist/src/vite/docsExtractor.js +13 -0
- package/dist/src/vite/fileAccess.d.ts +75 -0
- package/dist/src/vite/fileAccess.js +199 -0
- package/dist/src/vite/forgebookPlugin.d.ts +1 -1
- package/dist/src/vite/forgebookPlugin.js +67 -98
- package/dist/src/vite/framesServer.js +21 -5
- package/dist/src/vite/generatedModules.d.ts +23 -0
- package/dist/src/vite/generatedModules.js +58 -0
- package/dist/src/vite/hotSnippets.js +7 -3
- package/dist/src/vite/indexStoryFile.d.ts +2 -2
- package/dist/src/vite/indexStoryFile.js +2 -2
- package/dist/src/vite/indexedParameters.d.ts +1 -1
- package/dist/src/vite/indexedParameters.js +21 -1
- package/dist/src/vite/originGuard.d.ts +14 -4
- package/dist/src/vite/originGuard.js +15 -6
- package/dist/src/vite/pages.d.ts +3 -2
- package/dist/src/vite/pages.js +23 -16
- package/dist/src/vite/pluginIds.d.ts +24 -2
- package/dist/src/vite/pluginIds.js +44 -6
- package/dist/src/vite/pluginModules.d.ts +39 -10
- package/dist/src/vite/pluginModules.js +67 -22
- package/dist/src/vite/prebundled.js +2 -1
- package/dist/src/vite/searchModule.d.ts +6 -4
- package/dist/src/vite/searchModule.js +8 -7
- package/dist/src/vite/storyFilesModule.d.ts +59 -27
- package/dist/src/vite/storyFilesModule.js +88 -58
- package/dist/src/vite/storyPatterns.d.ts +39 -0
- package/dist/src/vite/storyPatterns.js +100 -0
- package/dist/src/vite/textQueries.d.ts +7 -1
- package/dist/src/vite/textQueries.js +7 -1
- package/package.json +4 -4
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
* @remarks
|
|
7
7
|
* Vite's CORS lets any page on `localhost` or `127.0.0.1` read the dev server, whatever its port: a frame on a second
|
|
8
8
|
* port would read the catalogue's agent API and files as before. So the catalogue refuses a request another origin
|
|
9
|
-
* sends, unless it
|
|
9
|
+
* sends, unless it opens one of its pages (a link, an embed) or a public file, which shows it but lets nobody read it.
|
|
10
|
+
* No other address is opened for another origin's page: a server's route acts when opened (`/__open-in-editor` opens a
|
|
11
|
+
* file), and a module or a source file has no use as a page.
|
|
12
|
+
*
|
|
13
|
+
* Vite checks `Host` first, on both ports, against `server.allowedHosts`: a page that reaches `127.0.0.1` through its
|
|
14
|
+
* own domain (DNS rebinding) is not told apart here, since it is same-origin for its browser, and over plain HTTP on
|
|
15
|
+
* that domain its browser sends no `Sec-Fetch-*`.
|
|
10
16
|
*
|
|
11
17
|
* The frames' origin would otherwise serve everything the catalogue's does, and a story's script would read the
|
|
12
18
|
* project from there. It serves a script or a `fetch` (whose body a script reads) only for a module that another
|
|
@@ -41,6 +47,8 @@ const OPAQUE_DESTS = new Set([
|
|
|
41
47
|
]);
|
|
42
48
|
/** The queries that ask Vite for a module made from a file (its text, its address…), never a file as it is. */
|
|
43
49
|
const TRANSFORM_QUERY = /[?&](?:raw|import|inline|url|worker|worker_file|sharedworker)(?:[&=]|$)/;
|
|
50
|
+
/** The catalogue's pages, by their addresses: what another origin's page may open, with public files and framed routes. */
|
|
51
|
+
const CATALOGUE_PAGES = new Set(["/", "/index.html", FRAME_PAGE_PATH]);
|
|
44
52
|
/** The dev server's own routes (`/__forgebook/api/`, `/__open-in-editor`): never a story's. */
|
|
45
53
|
const SERVER_ROUTE_PREFIX = "/__";
|
|
46
54
|
/**
|
|
@@ -88,18 +96,19 @@ const isAnyFromAnotherOrigin = (request) => request.site === undefined
|
|
|
88
96
|
const isDocumentRequest = (request) => request.mode === "navigate" || DOCUMENT_DESTS.has(request.dest ?? "");
|
|
89
97
|
/**
|
|
90
98
|
* What the catalogue's origin does with a request: the frame page goes to the frames' origin, another origin's
|
|
91
|
-
* request is refused, the rest is served.
|
|
99
|
+
* request is refused unless it opens a page or a public file, the rest is served.
|
|
92
100
|
*
|
|
93
101
|
* @param request - what the browser says of it.
|
|
94
102
|
* @param framedPages - the server's routes that are pages made to be framed by another origin's page (a client's
|
|
95
103
|
* inline preview), which only show a story and act on nothing.
|
|
104
|
+
* @param isPublic - whether a path names a file of the public folder; asked only of another origin's navigation.
|
|
96
105
|
*/
|
|
97
|
-
export const catalogueAnswer = (request, framedPages) => {
|
|
106
|
+
export const catalogueAnswer = (request, framedPages, isPublic = () => false) => {
|
|
98
107
|
if (isFromAnotherOrigin(request))
|
|
99
108
|
return "refuse";
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
if (request
|
|
109
|
+
const isOpenable = () => CATALOGUE_PAGES.has(request.path) ||
|
|
110
|
+
(isDocumentRequest(request) && (framedPages.has(request.path) || isPublic(request.path)));
|
|
111
|
+
if (isAnyFromAnotherOrigin(request) && !isOpenable())
|
|
103
112
|
return "refuse";
|
|
104
113
|
return request.path === FRAME_PAGE_PATH ? "to-frames" : "serve";
|
|
105
114
|
};
|
package/dist/src/vite/pages.d.ts
CHANGED
|
@@ -106,8 +106,9 @@ export declare const frameEntry: (config: ResolvedConfig, axe?: AxeAddress) => s
|
|
|
106
106
|
*/
|
|
107
107
|
export declare const agentSourcesModule: (config: ResolvedConfig) => string;
|
|
108
108
|
/**
|
|
109
|
-
* The source of the project's own stories and docs pages: one
|
|
110
|
-
*
|
|
109
|
+
* The source of the project's own stories and docs pages: its `stories` as one group of story files and its `docs` as
|
|
110
|
+
* one group of docs pages, each imported by its patterns (`FILES_SPECIFIER_PREFIX`), so a `!` pattern leaves files out
|
|
111
|
+
* of what all the others list and a file two patterns list comes once; named after the catalogue.
|
|
111
112
|
*
|
|
112
113
|
* @param config - the configuration.
|
|
113
114
|
*/
|
package/dist/src/vite/pages.js
CHANGED
|
@@ -18,6 +18,7 @@ import { LOAD_RELOADS_KEY } from "../frame/staleModule.js";
|
|
|
18
18
|
import { PREVIEWS_EVENT } from "../hotModules.js";
|
|
19
19
|
import { PLAY_TOOLS_PACKAGES } from "./configFile.js";
|
|
20
20
|
import { pluginFrameModule } from "./pluginConfig.js";
|
|
21
|
+
import { DOCS_PAGES_SPECIFIER_PREFIX, FILES_SPECIFIER_PREFIX, storyFilesGroupText } from "./storyFilesModule.js";
|
|
21
22
|
import { HOME_QUERY } from "./textQueries.js";
|
|
22
23
|
import { VITE_PATHS } from "./vitePaths.js";
|
|
23
24
|
/** The pages, by their file name. */
|
|
@@ -402,22 +403,28 @@ export const agentSourcesModule = (config) => {
|
|
|
402
403
|
return [...sources.imports, `export const sources = ${sources.list};`, ""].join("\n");
|
|
403
404
|
};
|
|
404
405
|
/**
|
|
405
|
-
* The source of the project's own stories and docs pages: one
|
|
406
|
-
*
|
|
406
|
+
* The source of the project's own stories and docs pages: its `stories` as one group of story files and its `docs` as
|
|
407
|
+
* one group of docs pages, each imported by its patterns (`FILES_SPECIFIER_PREFIX`), so a `!` pattern leaves files out
|
|
408
|
+
* of what all the others list and a file two patterns list comes once; named after the catalogue.
|
|
407
409
|
*
|
|
408
410
|
* @param config - the configuration.
|
|
409
411
|
*/
|
|
410
|
-
export const storiesSourceModule = (config) =>
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
? []
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
412
|
+
export const storiesSourceModule = (config) => {
|
|
413
|
+
// the configuration's folder in Vite's form, as the plugin names an importer's: the patterns are relative to it
|
|
414
|
+
const folder = VITE_PATHS.normalize(config.dir);
|
|
415
|
+
const group = (prefix, patterns) => codeLiteral(`${prefix}${storyFilesGroupText(folder, patterns)}`);
|
|
416
|
+
const hasStories = config.stories.length > 0;
|
|
417
|
+
const hasDocs = config.docs.length > 0;
|
|
418
|
+
return [
|
|
419
|
+
...(hasStories ? [`import files from ${group(FILES_SPECIFIER_PREFIX, config.stories)};`] : []),
|
|
420
|
+
...(hasDocs ? [`import docs from ${group(DOCS_PAGES_SPECIFIER_PREFIX, config.docs)};`] : []),
|
|
421
|
+
"export const source = {",
|
|
422
|
+
` id: ${codeLiteral(OWN_SOURCE_ID)},`,
|
|
423
|
+
` name: ${codeLiteral(config.title)},`,
|
|
424
|
+
` files: [${hasStories ? "files" : ""}],`,
|
|
425
|
+
...(hasDocs ? [" docs: [docs],"] : []),
|
|
426
|
+
" sheets: { required: [], theme: [], restyled: [] }",
|
|
427
|
+
"};",
|
|
428
|
+
""
|
|
429
|
+
].join("\n");
|
|
430
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** The id of a
|
|
2
|
-
export declare const DOCS_PAGES_PREFIX = "\
|
|
1
|
+
/** The id of a group of docs pages: virtual, with the declaring module's folder and the patterns after it. */
|
|
2
|
+
export declare const DOCS_PAGES_PREFIX = "\0virtual:forgebook-docs-pages:";
|
|
3
3
|
/**
|
|
4
4
|
* The id of a pattern's module, when an import asks for one: its story files, or its docs pages.
|
|
5
5
|
*
|
|
@@ -14,6 +14,28 @@ export declare const patternId: (source: string, folder: string) => string | nul
|
|
|
14
14
|
* @param source - the import's specifier.
|
|
15
15
|
*/
|
|
16
16
|
export declare const virtualId: (source: string) => string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Whether an id names a group's module: one whose patterns are written in the id itself, so that whoever writes the id
|
|
19
|
+
* chooses what the plugin reads.
|
|
20
|
+
*
|
|
21
|
+
* @param id - the module's id.
|
|
22
|
+
*/
|
|
23
|
+
export declare const isGroupId: (id: string) => boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The group a project's module names for a group's module: the story files of their "Used in", reach, search index and
|
|
26
|
+
* texts, the docs pages of their search index. Those read the same files and only their group's module imports them, so
|
|
27
|
+
* a client that already holds the group's module needs no other import to have been seen.
|
|
28
|
+
*
|
|
29
|
+
* @param id - a group's module's id.
|
|
30
|
+
*/
|
|
31
|
+
export declare const namingGroupOf: (id: string) => string;
|
|
32
|
+
/**
|
|
33
|
+
* Whether a module's text names a group. Its transform must run for the plugin to see the import, so a cache of
|
|
34
|
+
* transforms must not keep it.
|
|
35
|
+
*
|
|
36
|
+
* @param code - the module's text.
|
|
37
|
+
*/
|
|
38
|
+
export declare const namesGroup: (code: string) => boolean;
|
|
17
39
|
/** The resolved id of the configuration's data module. */
|
|
18
40
|
export declare const CONFIG_ID = "\0virtual:forgebook/config";
|
|
19
41
|
/** The resolved id of the design tokens' module. */
|
|
@@ -6,20 +6,20 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { CONFIG_MODULE, TOKENS_MODULE } from "./pages.js";
|
|
8
8
|
import { FILES_PREFIX } from "./pluginModules.js";
|
|
9
|
-
import { PAGES_SEARCH_PREFIX, REACH_PREFIX, SEARCH_PREFIX, storyFilesGroupText, TEXTS_PREFIX, USAGE_PREFIX } from "./storyFilesModule.js";
|
|
9
|
+
import { DOCS_PAGES_SPECIFIER_PREFIX, FILES_SPECIFIER_PREFIX, GROUP_SEPARATOR, PAGES_SEARCH_PREFIX, REACH_PREFIX, SEARCH_PREFIX, storyFilesGroupText, TEXTS_PREFIX, USAGE_PREFIX } from "./storyFilesModule.js";
|
|
10
10
|
/** The query that asks for the story files a pattern matches (`../src/**\/*.stories.tsx?forgebook-files`). */
|
|
11
11
|
const FILES_QUERY = "?forgebook-files";
|
|
12
12
|
/** The query that asks for the docs pages a pattern matches (`./docs/*.md?forgebook-docs-pages`). */
|
|
13
13
|
const DOCS_PAGES_QUERY = "?forgebook-docs-pages";
|
|
14
|
-
/** The id of a
|
|
15
|
-
export const DOCS_PAGES_PREFIX =
|
|
14
|
+
/** The id of a group of docs pages: virtual, with the declaring module's folder and the patterns after it. */
|
|
15
|
+
export const DOCS_PAGES_PREFIX = `\0${DOCS_PAGES_SPECIFIER_PREFIX}`;
|
|
16
16
|
/**
|
|
17
17
|
* The id of a `?forgebook-files` module: its prefix, then its group (`storyFilesGroupText`), which holds no `..`.
|
|
18
18
|
*
|
|
19
19
|
* @param folder - the importing module's folder.
|
|
20
20
|
* @param pattern - the pattern as the import writes it.
|
|
21
21
|
*/
|
|
22
|
-
const filesId = (folder, pattern) => `${FILES_PREFIX}${storyFilesGroupText(folder, pattern)}`;
|
|
22
|
+
const filesId = (folder, pattern) => `${FILES_PREFIX}${storyFilesGroupText(folder, [pattern])}`;
|
|
23
23
|
/**
|
|
24
24
|
* The id of a pattern's module, when an import asks for one: its story files, or its docs pages.
|
|
25
25
|
*
|
|
@@ -27,15 +27,23 @@ const filesId = (folder, pattern) => `${FILES_PREFIX}${storyFilesGroupText(folde
|
|
|
27
27
|
* @param folder - the importing module's folder.
|
|
28
28
|
*/
|
|
29
29
|
export const patternId = (source, folder) => {
|
|
30
|
+
// the separator of a group's id: a folder that holds it would read back as patterns of its own
|
|
31
|
+
if (folder.includes(GROUP_SEPARATOR))
|
|
32
|
+
return null;
|
|
30
33
|
if (source.endsWith(FILES_QUERY))
|
|
31
34
|
return filesId(folder, source.slice(0, -FILES_QUERY.length));
|
|
32
35
|
if (!source.endsWith(DOCS_PAGES_QUERY))
|
|
33
36
|
return null;
|
|
34
37
|
const pattern = source.slice(0, -DOCS_PAGES_QUERY.length);
|
|
35
|
-
return `${DOCS_PAGES_PREFIX}${storyFilesGroupText(folder, pattern)}`;
|
|
38
|
+
return `${DOCS_PAGES_PREFIX}${storyFilesGroupText(folder, [pattern])}`;
|
|
36
39
|
};
|
|
37
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* The specifiers' prefixes of a group's virtual modules: the group named by its patterns (story files or docs pages),
|
|
42
|
+
* its "Used in", its reach, its search indexes, its texts.
|
|
43
|
+
*/
|
|
38
44
|
const VIRTUAL_PREFIXES = [
|
|
45
|
+
FILES_SPECIFIER_PREFIX,
|
|
46
|
+
DOCS_PAGES_SPECIFIER_PREFIX,
|
|
39
47
|
USAGE_PREFIX,
|
|
40
48
|
REACH_PREFIX,
|
|
41
49
|
SEARCH_PREFIX,
|
|
@@ -55,6 +63,36 @@ export const virtualId = (source) => {
|
|
|
55
63
|
return TOKENS_ID;
|
|
56
64
|
return VIRTUAL_PREFIXES.some((prefix) => source.startsWith(prefix)) ? `\0${source}` : undefined;
|
|
57
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* Whether an id names a group's module: one whose patterns are written in the id itself, so that whoever writes the id
|
|
68
|
+
* chooses what the plugin reads.
|
|
69
|
+
*
|
|
70
|
+
* @param id - the module's id.
|
|
71
|
+
*/
|
|
72
|
+
export const isGroupId = (id) => VIRTUAL_PREFIXES.some((prefix) => id.startsWith(`\0${prefix}`));
|
|
73
|
+
/** The modules that read a group of story files' own files: named once its story files are. */
|
|
74
|
+
const STORY_FILES_READERS = [USAGE_PREFIX, REACH_PREFIX, SEARCH_PREFIX, TEXTS_PREFIX];
|
|
75
|
+
/**
|
|
76
|
+
* The group a project's module names for a group's module: the story files of their "Used in", reach, search index and
|
|
77
|
+
* texts, the docs pages of their search index. Those read the same files and only their group's module imports them, so
|
|
78
|
+
* a client that already holds the group's module needs no other import to have been seen.
|
|
79
|
+
*
|
|
80
|
+
* @param id - a group's module's id.
|
|
81
|
+
*/
|
|
82
|
+
export const namingGroupOf = (id) => {
|
|
83
|
+
const pagesSearch = `\0${PAGES_SEARCH_PREFIX}`;
|
|
84
|
+
if (id.startsWith(pagesSearch))
|
|
85
|
+
return `${DOCS_PAGES_PREFIX}${id.slice(pagesSearch.length)}`;
|
|
86
|
+
const reader = STORY_FILES_READERS.map((prefix) => `\0${prefix}`).find((mark) => id.startsWith(mark));
|
|
87
|
+
return reader === undefined ? id : `${FILES_PREFIX}${id.slice(reader.length)}`;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Whether a module's text names a group. Its transform must run for the plugin to see the import, so a cache of
|
|
91
|
+
* transforms must not keep it.
|
|
92
|
+
*
|
|
93
|
+
* @param code - the module's text.
|
|
94
|
+
*/
|
|
95
|
+
export const namesGroup = (code) => [FILES_QUERY, DOCS_PAGES_QUERY, ...VIRTUAL_PREFIXES].some((name) => code.includes(name));
|
|
58
96
|
/** The resolved id of the configuration's data module. */
|
|
59
97
|
export const CONFIG_ID = `\0${CONFIG_MODULE}`;
|
|
60
98
|
/** The resolved id of the design tokens' module. */
|
|
@@ -11,9 +11,12 @@
|
|
|
11
11
|
import type { DiskCache } from "./diskCache.ts";
|
|
12
12
|
import type { DocsExtractor, DocsResult } from "./docsExtractor.ts";
|
|
13
13
|
import type { PackJson } from "./packedModule.ts";
|
|
14
|
-
import { type GroupLoaders, type IndexedStoryFile, type KeptIndex } from "./storyFilesModule.ts";
|
|
15
|
-
/**
|
|
16
|
-
|
|
14
|
+
import { type GroupLoaders, type IndexedStoryFile, type IsFileKept, type KeptIndex } from "./storyFilesModule.ts";
|
|
15
|
+
/**
|
|
16
|
+
* The id of a group of story files' module: virtual, with the declaring module's folder and the patterns after it,
|
|
17
|
+
* whether a `?forgebook-files` import or the group's specifier (`FILES_SPECIFIER_PREFIX`) names it.
|
|
18
|
+
*/
|
|
19
|
+
export declare const FILES_PREFIX = "\0virtual:forgebook-files:";
|
|
17
20
|
/** The resolved id of a group's "Used in" module: Rollup's mark of a virtual module, then its import's specifier. */
|
|
18
21
|
export declare const USAGE_ID_PREFIX = "\0virtual:forgebook-usage:";
|
|
19
22
|
/** The resolved id of a group's reach module, the same way. */
|
|
@@ -42,7 +45,7 @@ export declare const docsModule: (component: DocsResult, watch: (file: string) =
|
|
|
42
45
|
moduleType: "js";
|
|
43
46
|
};
|
|
44
47
|
/**
|
|
45
|
-
* The module of a
|
|
48
|
+
* The module of a group of story files: every listed story file's index and loaders; with the files, indexed,
|
|
46
49
|
* which the dev server keeps to tell an edit that changes the list.
|
|
47
50
|
*
|
|
48
51
|
* @param id - the module's id (`FILES_PREFIX`, then the group: `storyFilesGroupText`).
|
|
@@ -52,13 +55,35 @@ export declare const docsModule: (component: DocsResult, watch: (file: string) =
|
|
|
52
55
|
* @param warm - starts reading the docs of a story file ahead of its request; none in a test run.
|
|
53
56
|
* @param startTexts - a build's: starts reading the files' docs, code and pages, which the module imports from the
|
|
54
57
|
* group's texts module (`builtTexts.ts`); none imports each from its query.
|
|
58
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
55
59
|
* @throws when a story file cannot be indexed.
|
|
56
60
|
*/
|
|
57
|
-
export declare const patternModule: (id: string, watch: (file: string) => void, loaders: GroupLoaders, cache: DiskCache<KeptIndex> | undefined, warm: ((storyFile: string) => void) | undefined, startTexts?: (files: readonly IndexedStoryFile[]) => void) => {
|
|
61
|
+
export declare const patternModule: (id: string, watch: (file: string) => void, loaders: GroupLoaders, cache: DiskCache<KeptIndex> | undefined, warm: ((storyFile: string) => void) | undefined, startTexts?: (files: readonly IndexedStoryFile[]) => void, isKept?: IsFileKept) => {
|
|
58
62
|
code: string;
|
|
59
63
|
moduleType: "js";
|
|
60
64
|
files: readonly IndexedStoryFile[];
|
|
61
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* Whether a story file added or removed changes what a group of story files lists: listed now and not when its module
|
|
68
|
+
* was served, or the other way round. A file no pattern lists, or one a `!` pattern leaves out, changes nothing, so
|
|
69
|
+
* the pages need no reload for it.
|
|
70
|
+
*
|
|
71
|
+
* @param id - the group's module's id (`FILES_PREFIX`, then the group).
|
|
72
|
+
* @param listed - the files its module listed when served, absolute in Vite's form; none when it could not be made.
|
|
73
|
+
* @param file - the file added or removed.
|
|
74
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
75
|
+
*/
|
|
76
|
+
export declare const isListingChanged: (id: string, listed: ReadonlySet<string> | undefined, file: string, isKept?: IsFileKept) => boolean;
|
|
77
|
+
/**
|
|
78
|
+
* The modules a story file added or removed renews: the groups whose list it changes (`isListingChanged`) and, with
|
|
79
|
+
* them, the modules that read their files; none when it changes no list.
|
|
80
|
+
*
|
|
81
|
+
* @param served - the groups' modules, with the files each listed when served.
|
|
82
|
+
* @param file - the file added or removed.
|
|
83
|
+
* @param readers - the modules that read the groups' files: their "Used in" and search indexes.
|
|
84
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
85
|
+
*/
|
|
86
|
+
export declare const listingRenewals: (served: ReadonlyMap<string, ReadonlySet<string> | undefined>, file: string, readers: readonly string[], isKept?: IsFileKept) => readonly string[] | undefined;
|
|
62
87
|
/**
|
|
63
88
|
* A group's "Used in" module: for each component, the components that use it, packed once per title and list of
|
|
64
89
|
* stories (`packedUsage`), which a page reads.
|
|
@@ -68,8 +93,9 @@ export declare const patternModule: (id: string, watch: (file: string) => void,
|
|
|
68
93
|
* @param usage - reads the facts in the docs worker.
|
|
69
94
|
* @param cache - the pattern's index kept between starts; none reads every file.
|
|
70
95
|
* @param pack - writes the module's JSON as its value: as it is on a dev server, in a gzipped file of a build's.
|
|
96
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
71
97
|
*/
|
|
72
|
-
export declare const usageModule: (id: string, watch: (file: string) => void, usage: DocsExtractor["usage"], cache: DiskCache<KeptIndex> | undefined, pack: PackJson) => Promise<{
|
|
98
|
+
export declare const usageModule: (id: string, watch: (file: string) => void, usage: DocsExtractor["usage"], cache: DiskCache<KeptIndex> | undefined, pack: PackJson, isKept?: IsFileKept) => Promise<{
|
|
73
99
|
code: string;
|
|
74
100
|
moduleType: "js";
|
|
75
101
|
}>;
|
|
@@ -82,8 +108,9 @@ export declare const usageModule: (id: string, watch: (file: string) => void, us
|
|
|
82
108
|
* @param watch - adds a file whose edit renews the module (each story file).
|
|
83
109
|
* @param usage - reads the facts in the docs worker.
|
|
84
110
|
* @param cache - the pattern's index kept between starts; none reads every file.
|
|
111
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
85
112
|
*/
|
|
86
|
-
export declare const reachModule: (id: string, watch: (file: string) => void, usage: DocsExtractor["usage"], cache: DiskCache<KeptIndex> | undefined) => Promise<{
|
|
113
|
+
export declare const reachModule: (id: string, watch: (file: string) => void, usage: DocsExtractor["usage"], cache: DiskCache<KeptIndex> | undefined, isKept?: IsFileKept) => Promise<{
|
|
87
114
|
code: string;
|
|
88
115
|
moduleType: "js";
|
|
89
116
|
}>;
|
|
@@ -103,13 +130,14 @@ export type SearchIndexModule = {
|
|
|
103
130
|
*
|
|
104
131
|
* @param id - the module's id.
|
|
105
132
|
* @param watch - adds a file whose edit renews the module.
|
|
106
|
-
* @param read - a story file's component docs,
|
|
133
|
+
* @param read - a story file's component docs, how the module writes its JSON, and which listed files may be read.
|
|
107
134
|
* @returns the index; none for another id.
|
|
108
135
|
*/
|
|
109
136
|
export declare const searchIndexModule: (id: string, watch: (file: string) => void, read: {
|
|
110
137
|
readonly docsOf: (storyFile: string) => Promise<DocsResult>;
|
|
111
138
|
readonly isServing: boolean;
|
|
112
139
|
readonly pack: PackJson;
|
|
140
|
+
readonly isKept: IsFileKept;
|
|
113
141
|
}) => Promise<SearchIndexModule | undefined>;
|
|
114
142
|
/** What a catalogue's search indexes read and tell: what `searchIndexes` makes. */
|
|
115
143
|
export type SearchIndexes = {
|
|
@@ -130,11 +158,12 @@ export type SearchIndexes = {
|
|
|
130
158
|
/**
|
|
131
159
|
* The search's indexes of a plugin: a build reads each component's docs once, for its page and its index.
|
|
132
160
|
*
|
|
133
|
-
* @param read - reads a story file's component docs, says whether a dev server runs,
|
|
134
|
-
* modules an edit renews (a docs pages' index with the docs pages').
|
|
161
|
+
* @param read - reads a story file's component docs, says whether a dev server runs, keeps each index's id with the
|
|
162
|
+
* modules an edit renews (a docs pages' index with the docs pages'), and says which listed files may be read.
|
|
135
163
|
*/
|
|
136
164
|
export declare const searchIndexes: (read: {
|
|
137
165
|
readonly extract: (storyFile: string) => Promise<DocsResult>;
|
|
138
166
|
readonly isServing: () => boolean;
|
|
139
167
|
readonly track: (id: string, isPages: boolean) => void;
|
|
168
|
+
readonly isKept: IsFileKept;
|
|
140
169
|
}) => SearchIndexes;
|
|
@@ -10,11 +10,15 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { codeLiteral } from "../codeLiteral.js";
|
|
12
12
|
import { packedUsage } from "../usedIn.js";
|
|
13
|
-
import { indexedStoryFiles, PAGES_SEARCH_PREFIX, REACH_PREFIX, SEARCH_PREFIX, storyFilesCode, storyFilesGroupOf, TEXTS_PREFIX, USAGE_PREFIX } from "./storyFilesModule.js";
|
|
13
|
+
import { EVERY_FILE, FILES_SPECIFIER_PREFIX, indexedStoryFiles, PAGES_SEARCH_PREFIX, REACH_PREFIX, SEARCH_PREFIX, storyFileKeys, storyFilesCode, storyFilesGroupOf, TEXTS_PREFIX, USAGE_PREFIX } from "./storyFilesModule.js";
|
|
14
14
|
import { storyReach } from "./storyReach.js";
|
|
15
15
|
import { joinedUsage } from "./usageModule.js";
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
import { VITE_PATHS } from "./vitePaths.js";
|
|
17
|
+
/**
|
|
18
|
+
* The id of a group of story files' module: virtual, with the declaring module's folder and the patterns after it,
|
|
19
|
+
* whether a `?forgebook-files` import or the group's specifier (`FILES_SPECIFIER_PREFIX`) names it.
|
|
20
|
+
*/
|
|
21
|
+
export const FILES_PREFIX = `\0${FILES_SPECIFIER_PREFIX}`;
|
|
18
22
|
/** The resolved id of a group's "Used in" module: Rollup's mark of a virtual module, then its import's specifier. */
|
|
19
23
|
export const USAGE_ID_PREFIX = `\0${USAGE_PREFIX}`;
|
|
20
24
|
/** The resolved id of a group's reach module, the same way. */
|
|
@@ -51,7 +55,7 @@ export const docsModule = (component, watch) => ({
|
|
|
51
55
|
moduleType: "js"
|
|
52
56
|
});
|
|
53
57
|
/**
|
|
54
|
-
* The module of a
|
|
58
|
+
* The module of a group of story files: every listed story file's index and loaders; with the files, indexed,
|
|
55
59
|
* which the dev server keeps to tell an edit that changes the list.
|
|
56
60
|
*
|
|
57
61
|
* @param id - the module's id (`FILES_PREFIX`, then the group: `storyFilesGroupText`).
|
|
@@ -61,18 +65,51 @@ export const docsModule = (component, watch) => ({
|
|
|
61
65
|
* @param warm - starts reading the docs of a story file ahead of its request; none in a test run.
|
|
62
66
|
* @param startTexts - a build's: starts reading the files' docs, code and pages, which the module imports from the
|
|
63
67
|
* group's texts module (`builtTexts.ts`); none imports each from its query.
|
|
68
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
64
69
|
* @throws when a story file cannot be indexed.
|
|
65
70
|
*/
|
|
66
|
-
export const patternModule = (id, watch, loaders, cache, warm, startTexts) => {
|
|
67
|
-
const { root,
|
|
68
|
-
const files = indexedStoryFiles(root,
|
|
71
|
+
export const patternModule = (id, watch, loaders, cache, warm, startTexts, isKept = EVERY_FILE) => {
|
|
72
|
+
const { root, patterns } = storyFilesGroupOf(id.slice(FILES_PREFIX.length));
|
|
73
|
+
const files = indexedStoryFiles(root, patterns, watch, cache, isKept);
|
|
69
74
|
const [first] = files;
|
|
70
75
|
if (first !== undefined)
|
|
71
76
|
warm?.(first.file);
|
|
72
77
|
startTexts?.(files);
|
|
73
|
-
const code = storyFilesCode(root,
|
|
78
|
+
const code = storyFilesCode(root, patterns, files, loaders, startTexts !== undefined);
|
|
74
79
|
return { code, moduleType: "js", files };
|
|
75
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Whether a story file added or removed changes what a group of story files lists: listed now and not when its module
|
|
83
|
+
* was served, or the other way round. A file no pattern lists, or one a `!` pattern leaves out, changes nothing, so
|
|
84
|
+
* the pages need no reload for it.
|
|
85
|
+
*
|
|
86
|
+
* @param id - the group's module's id (`FILES_PREFIX`, then the group).
|
|
87
|
+
* @param listed - the files its module listed when served, absolute in Vite's form; none when it could not be made.
|
|
88
|
+
* @param file - the file added or removed.
|
|
89
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
90
|
+
*/
|
|
91
|
+
export const isListingChanged = (id, listed, file, isKept = EVERY_FILE) => {
|
|
92
|
+
if (listed === undefined)
|
|
93
|
+
return true;
|
|
94
|
+
const { root, patterns } = storyFilesGroupOf(id.slice(FILES_PREFIX.length));
|
|
95
|
+
const isListed = storyFileKeys(root, patterns, isKept).includes(VITE_PATHS.relativeKey(root, file));
|
|
96
|
+
return isListed !== listed.has(VITE_PATHS.normalize(file));
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* The modules a story file added or removed renews: the groups whose list it changes (`isListingChanged`) and, with
|
|
100
|
+
* them, the modules that read their files; none when it changes no list.
|
|
101
|
+
*
|
|
102
|
+
* @param served - the groups' modules, with the files each listed when served.
|
|
103
|
+
* @param file - the file added or removed.
|
|
104
|
+
* @param readers - the modules that read the groups' files: their "Used in" and search indexes.
|
|
105
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
106
|
+
*/
|
|
107
|
+
export const listingRenewals = (served, file, readers, isKept = EVERY_FILE) => {
|
|
108
|
+
const changed = [...served]
|
|
109
|
+
.filter(([id, listed]) => isListingChanged(id, listed, file, isKept))
|
|
110
|
+
.map(([id]) => id);
|
|
111
|
+
return changed.length === 0 ? undefined : [...changed, ...readers];
|
|
112
|
+
};
|
|
76
113
|
/**
|
|
77
114
|
* A group's facts: its story files indexed, what their stories render read in the docs worker.
|
|
78
115
|
*
|
|
@@ -80,10 +117,11 @@ export const patternModule = (id, watch, loaders, cache, warm, startTexts) => {
|
|
|
80
117
|
* @param watch - adds a file whose edit renews the module (each story file).
|
|
81
118
|
* @param usage - reads the facts in the docs worker.
|
|
82
119
|
* @param cache - the pattern's index kept between starts; none reads every file.
|
|
120
|
+
* @param isKept - whether a listed file may be read.
|
|
83
121
|
*/
|
|
84
|
-
const groupUsage = async (group, watch, usage, cache) => {
|
|
85
|
-
const { root,
|
|
86
|
-
const files = indexedStoryFiles(root,
|
|
122
|
+
const groupUsage = async (group, watch, usage, cache, isKept) => {
|
|
123
|
+
const { root, patterns } = storyFilesGroupOf(group);
|
|
124
|
+
const files = indexedStoryFiles(root, patterns, watch, cache, isKept);
|
|
87
125
|
const graph = await usage(files.map((file) => ({
|
|
88
126
|
storyFile: file.file,
|
|
89
127
|
exports: file.index.stories.map((story) => story.exportName)
|
|
@@ -99,9 +137,10 @@ const groupUsage = async (group, watch, usage, cache) => {
|
|
|
99
137
|
* @param usage - reads the facts in the docs worker.
|
|
100
138
|
* @param cache - the pattern's index kept between starts; none reads every file.
|
|
101
139
|
* @param pack - writes the module's JSON as its value: as it is on a dev server, in a gzipped file of a build's.
|
|
140
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
102
141
|
*/
|
|
103
|
-
export const usageModule = async (id, watch, usage, cache, pack) => {
|
|
104
|
-
const { files, graph } = await groupUsage(id.slice(USAGE_ID_PREFIX.length), watch, usage, cache);
|
|
142
|
+
export const usageModule = async (id, watch, usage, cache, pack, isKept = EVERY_FILE) => {
|
|
143
|
+
const { files, graph } = await groupUsage(id.slice(USAGE_ID_PREFIX.length), watch, usage, cache, isKept);
|
|
105
144
|
const answer = typeof graph === "string"
|
|
106
145
|
? { error: graph }
|
|
107
146
|
: packedUsage(joinedUsage(graph, files.map((file) => ({
|
|
@@ -120,9 +159,10 @@ export const usageModule = async (id, watch, usage, cache, pack) => {
|
|
|
120
159
|
* @param watch - adds a file whose edit renews the module (each story file).
|
|
121
160
|
* @param usage - reads the facts in the docs worker.
|
|
122
161
|
* @param cache - the pattern's index kept between starts; none reads every file.
|
|
162
|
+
* @param isKept - whether a listed file may be read; every one by default.
|
|
123
163
|
*/
|
|
124
|
-
export const reachModule = async (id, watch, usage, cache) => {
|
|
125
|
-
const { files, graph } = await groupUsage(id.slice(REACH_ID_PREFIX.length), watch, usage, cache);
|
|
164
|
+
export const reachModule = async (id, watch, usage, cache, isKept = EVERY_FILE) => {
|
|
165
|
+
const { files, graph } = await groupUsage(id.slice(REACH_ID_PREFIX.length), watch, usage, cache, isKept);
|
|
126
166
|
const reach = typeof graph === "string"
|
|
127
167
|
? []
|
|
128
168
|
: storyReach(graph, files.map((file) => ({ storyFile: file.file, title: file.index.title })));
|
|
@@ -134,7 +174,7 @@ export const reachModule = async (id, watch, usage, cache) => {
|
|
|
134
174
|
*
|
|
135
175
|
* @param id - the module's id.
|
|
136
176
|
* @param watch - adds a file whose edit renews the module.
|
|
137
|
-
* @param read - a story file's component docs,
|
|
177
|
+
* @param read - a story file's component docs, how the module writes its JSON, and which listed files may be read.
|
|
138
178
|
* @returns the index; none for another id.
|
|
139
179
|
*/
|
|
140
180
|
export const searchIndexModule = async (id, watch, read) => {
|
|
@@ -142,17 +182,17 @@ export const searchIndexModule = async (id, watch, read) => {
|
|
|
142
182
|
if (!isPages && !id.startsWith(SEARCH_ID_PREFIX))
|
|
143
183
|
return undefined;
|
|
144
184
|
const { storySearchModule, pagesSearchModule } = await import("./searchModule.js");
|
|
145
|
-
const { root,
|
|
185
|
+
const { root, patterns } = storyFilesGroupOf(id.slice((isPages ? PAGES_SEARCH_ID_PREFIX : SEARCH_ID_PREFIX).length));
|
|
146
186
|
const code = isPages
|
|
147
|
-
? pagesSearchModule(root,
|
|
148
|
-
: await storySearchModule(root,
|
|
187
|
+
? pagesSearchModule(root, patterns, watch, read.pack, read.isKept)
|
|
188
|
+
: await storySearchModule(root, patterns, watch, read.docsOf, read.isServing, read.pack, read.isKept);
|
|
149
189
|
return { module: { code, moduleType: "js" }, isPages };
|
|
150
190
|
};
|
|
151
191
|
/**
|
|
152
192
|
* The search's indexes of a plugin: a build reads each component's docs once, for its page and its index.
|
|
153
193
|
*
|
|
154
|
-
* @param read - reads a story file's component docs, says whether a dev server runs,
|
|
155
|
-
* modules an edit renews (a docs pages' index with the docs pages').
|
|
194
|
+
* @param read - reads a story file's component docs, says whether a dev server runs, keeps each index's id with the
|
|
195
|
+
* modules an edit renews (a docs pages' index with the docs pages'), and says which listed files may be read.
|
|
156
196
|
*/
|
|
157
197
|
export const searchIndexes = (read) => {
|
|
158
198
|
const built = new Map();
|
|
@@ -166,7 +206,12 @@ export const searchIndexes = (read) => {
|
|
|
166
206
|
return {
|
|
167
207
|
docsOf,
|
|
168
208
|
moduleOf: async (id, watch, pack) => {
|
|
169
|
-
const search = await searchIndexModule(id, watch, {
|
|
209
|
+
const search = await searchIndexModule(id, watch, {
|
|
210
|
+
docsOf,
|
|
211
|
+
isServing: read.isServing(),
|
|
212
|
+
pack,
|
|
213
|
+
isKept: read.isKept
|
|
214
|
+
});
|
|
170
215
|
if (search === undefined)
|
|
171
216
|
return undefined;
|
|
172
217
|
read.track(id, search.isPages);
|
|
@@ -86,6 +86,7 @@ export const scannedEntries = (config, resolve, readText) => {
|
|
|
86
86
|
return [];
|
|
87
87
|
return [...text.matchAll(FILES_IMPORT)].flatMap((match) => match[1] === undefined ? [] : [VITE_PATHS.join(VITE_PATHS.dirname(file), match[1])]);
|
|
88
88
|
});
|
|
89
|
-
// the previews too: what they import loads with the first story, and found then it reloads the page
|
|
89
|
+
// the previews too: what they import loads with the first story, and found then it reloads the page; the project's
|
|
90
|
+
// `!` patterns stay as they are, which Vite's scanner reads as fast-glob does, from the same folder
|
|
90
91
|
return [...config.stories, ...fromSources, ...config.previews];
|
|
91
92
|
};
|
|
@@ -2,6 +2,7 @@ import type { DocBlock } from "../docPages.ts";
|
|
|
2
2
|
import type { SearchSection } from "../searchIndex.ts";
|
|
3
3
|
import type { DocsResult } from "./docsExtractor.ts";
|
|
4
4
|
import type { PackJson } from "./packedModule.ts";
|
|
5
|
+
import { type IsFileKept } from "./storyFilesModule.ts";
|
|
5
6
|
/**
|
|
6
7
|
* HTML as stretches of documentation, one per heading that carries an anchor.
|
|
7
8
|
*
|
|
@@ -20,7 +21,7 @@ export declare const blockSections: (blocks: readonly DocBlock[]) => SearchSecti
|
|
|
20
21
|
* A group of story files' search index, as the code of its module.
|
|
21
22
|
*
|
|
22
23
|
* @param root - the declaring module's folder.
|
|
23
|
-
* @param
|
|
24
|
+
* @param patterns - the group's patterns.
|
|
24
25
|
* @param watch - adds a file whose edit renews the module.
|
|
25
26
|
* @param extract - reads a story file's component.
|
|
26
27
|
* @param isServing - whether a dev server runs: only its tools read the problems, which name files on this computer, so
|
|
@@ -28,13 +29,14 @@ export declare const blockSections: (blocks: readonly DocBlock[]) => SearchSecti
|
|
|
28
29
|
* @param pack - writes the index's JSON as the module's value: as it is, or in a gzipped file of a build's own, which
|
|
29
30
|
* few visits read.
|
|
30
31
|
*/
|
|
31
|
-
export declare const storySearchModule: (root: string,
|
|
32
|
+
export declare const storySearchModule: (root: string, patterns: readonly string[], watch: (file: string) => void, extract: (storyFile: string) => Promise<DocsResult>, isServing: boolean, pack: PackJson, isKept?: IsFileKept) => Promise<string>;
|
|
32
33
|
/**
|
|
33
34
|
* A group of docs pages' search index, as the code of its module.
|
|
34
35
|
*
|
|
35
36
|
* @param root - the declaring module's folder.
|
|
36
|
-
* @param
|
|
37
|
+
* @param patterns - the group's patterns.
|
|
37
38
|
* @param watch - adds a file whose edit renews the module.
|
|
38
39
|
* @param pack - writes the index's JSON as the module's value.
|
|
40
|
+
* @param isKept - whether a listed page may be read; every one by default.
|
|
39
41
|
*/
|
|
40
|
-
export declare const pagesSearchModule: (root: string,
|
|
42
|
+
export declare const pagesSearchModule: (root: string, patterns: readonly string[], watch: (file: string) => void, pack: PackJson, isKept?: IsFileKept) => string;
|
|
@@ -14,7 +14,7 @@ import { readFileSync } from "node:fs";
|
|
|
14
14
|
import { componentPage } from "./componentPage.js";
|
|
15
15
|
import { compiledDocPage } from "./docPageMarkdown.js";
|
|
16
16
|
import { indexedDocPages } from "./docPagesModule.js";
|
|
17
|
-
import { indexedStoryFiles } from "./storyFilesModule.js";
|
|
17
|
+
import { EVERY_FILE, indexedStoryFiles } from "./storyFilesModule.js";
|
|
18
18
|
/** A heading of the pages' HTML: its anchor, and what is inside it. */
|
|
19
19
|
const HEADING = /<h[1-6] id="doc-([^"]*)"[^>]*>([\s\S]*?)<\/h[1-6]>/g;
|
|
20
20
|
/** A tag: `>` inside a quoted attribute does not end it. */
|
|
@@ -177,7 +177,7 @@ const entryOf = (file, read, watch) => {
|
|
|
177
177
|
* A group of story files' search index, as the code of its module.
|
|
178
178
|
*
|
|
179
179
|
* @param root - the declaring module's folder.
|
|
180
|
-
* @param
|
|
180
|
+
* @param patterns - the group's patterns.
|
|
181
181
|
* @param watch - adds a file whose edit renews the module.
|
|
182
182
|
* @param extract - reads a story file's component.
|
|
183
183
|
* @param isServing - whether a dev server runs: only its tools read the problems, which name files on this computer, so
|
|
@@ -185,8 +185,8 @@ const entryOf = (file, read, watch) => {
|
|
|
185
185
|
* @param pack - writes the index's JSON as the module's value: as it is, or in a gzipped file of a build's own, which
|
|
186
186
|
* few visits read.
|
|
187
187
|
*/
|
|
188
|
-
export const storySearchModule = async (root,
|
|
189
|
-
const files = indexedStoryFiles(root,
|
|
188
|
+
export const storySearchModule = async (root, patterns, watch, extract, isServing, pack, isKept = EVERY_FILE) => {
|
|
189
|
+
const files = indexedStoryFiles(root, patterns, watch, undefined, isKept);
|
|
190
190
|
const entries = await Promise.all(files.map(async (file) => ({ file, ...entryOf(file, await extract(file.file), watch) })));
|
|
191
191
|
const problems = entries.flatMap(({ problem }) => problem ?? []);
|
|
192
192
|
const index = {
|
|
@@ -199,12 +199,13 @@ export const storySearchModule = async (root, pattern, watch, extract, isServing
|
|
|
199
199
|
* A group of docs pages' search index, as the code of its module.
|
|
200
200
|
*
|
|
201
201
|
* @param root - the declaring module's folder.
|
|
202
|
-
* @param
|
|
202
|
+
* @param patterns - the group's patterns.
|
|
203
203
|
* @param watch - adds a file whose edit renews the module.
|
|
204
204
|
* @param pack - writes the index's JSON as the module's value.
|
|
205
|
+
* @param isKept - whether a listed page may be read; every one by default.
|
|
205
206
|
*/
|
|
206
|
-
export const pagesSearchModule = (root,
|
|
207
|
-
const pages = indexedDocPages(root,
|
|
207
|
+
export const pagesSearchModule = (root, patterns, watch, pack, isKept = EVERY_FILE) => {
|
|
208
|
+
const pages = indexedDocPages(root, patterns, watch, [], isKept).map(({ key, file }) => [
|
|
208
209
|
key,
|
|
209
210
|
blockSections(compiledDocPage(file, readFileSync(file, "utf8")).blocks)
|
|
210
211
|
]);
|