@markii/host 0.0.1 → 0.17.0-next.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/README.md +18 -2
- package/dist/browser-worker.js +639 -0
- package/dist/browser.d.ts +57 -0
- package/dist/browser.js +167 -0
- package/dist/conformance/host/01-plain-open/expected.json +5 -0
- package/dist/conformance/host/01-plain-open/note.mk.md +8 -0
- package/dist/conformance/host/01-plain-open/scenario.json +6 -0
- package/dist/conformance/host/02-run-manual-grant-accepted/expected.json +16 -0
- package/dist/conformance/host/02-run-manual-grant-accepted/note.mk.md +5 -0
- package/dist/conformance/host/02-run-manual-grant-accepted/scenario.json +14 -0
- package/dist/conformance/host/03-run-manual-grant-refused/expected.json +18 -0
- package/dist/conformance/host/03-run-manual-grant-refused/note.mk.md +5 -0
- package/dist/conformance/host/03-run-manual-grant-refused/scenario.json +14 -0
- package/dist/conformance/host/04-run-auto-write-denied/expected.json +16 -0
- package/dist/conformance/host/04-run-auto-write-denied/note.mk.md +10 -0
- package/dist/conformance/host/04-run-auto-write-denied/scenario.json +13 -0
- package/dist/conformance/host/05-export-html-pack-directive/expected.json +14 -0
- package/dist/conformance/host/05-export-html-pack-directive/note.mk.md +8 -0
- package/dist/conformance/host/05-export-html-pack-directive/scenario.json +6 -0
- package/dist/conformance/host/06-install-pack-then-render/expected.json +18 -0
- package/dist/conformance/host/06-install-pack-then-render/files/ana-1.0.0/pack.json +13 -0
- package/dist/conformance/host/06-install-pack-then-render/files/ana-1.0.0/webview.js +1 -0
- package/dist/conformance/host/06-install-pack-then-render/note.mk.md +5 -0
- package/dist/conformance/host/06-install-pack-then-render/scenario.json +15 -0
- package/dist/conformance/host/07-complete-in-directive/expected.json +14 -0
- package/dist/conformance/host/07-complete-in-directive/note.mk.md +3 -0
- package/dist/conformance/host/07-complete-in-directive/scenario.json +6 -0
- package/dist/conformance/host/08-hover-standard-component/expected.json +5 -0
- package/dist/conformance/host/08-hover-standard-component/note.mk.md +5 -0
- package/dist/conformance/host/08-hover-standard-component/scenario.json +6 -0
- package/dist/conformance/host/09-insert-skeleton/expected.json +5 -0
- package/dist/conformance/host/09-insert-skeleton/note.mk.md +4 -0
- package/dist/conformance/host/09-insert-skeleton/scenario.json +6 -0
- package/dist/conformance/host/10-scripts-disabled/expected.json +11 -0
- package/dist/conformance/host/10-scripts-disabled/note.mk.md +5 -0
- package/dist/conformance/host/10-scripts-disabled/scenario.json +9 -0
- package/dist/conformance/host/11-complete-closing-fence/expected.json +5 -0
- package/dist/conformance/host/11-complete-closing-fence/note.mk.md +5 -0
- package/dist/conformance/host/11-complete-closing-fence/scenario.json +12 -0
- package/dist/conformance/host/12-complete-nested-container/expected.json +5 -0
- package/dist/conformance/host/12-complete-nested-container/note.mk.md +5 -0
- package/dist/conformance/host/12-complete-nested-container/scenario.json +12 -0
- package/dist/conformance/host/13-install-pack-declined/expected.json +12 -0
- package/dist/conformance/host/13-install-pack-declined/files/ana-1.0.0/pack.json +13 -0
- package/dist/conformance/host/13-install-pack-declined/files/ana-1.0.0/webview.js +1 -0
- package/dist/conformance/host/13-install-pack-declined/note.mk.md +5 -0
- package/dist/conformance/host/13-install-pack-declined/scenario.json +10 -0
- package/dist/conformance/host/14-remove-pack/expected.json +14 -0
- package/dist/conformance/host/14-remove-pack/files/ana-1.0.0/pack.json +13 -0
- package/dist/conformance/host/14-remove-pack/files/ana-1.0.0/webview.js +1 -0
- package/dist/conformance/host/14-remove-pack/note.mk.md +5 -0
- package/dist/conformance/host/14-remove-pack/scenario.json +11 -0
- package/dist/conformance/host/15-load-packs-engine-views/expected.json +19 -0
- package/dist/conformance/host/15-load-packs-engine-views/files/duo-1.0.0/pack.json +9 -0
- package/dist/conformance/host/15-load-packs-engine-views/files/duo-1.0.0/webview.js +1 -0
- package/dist/conformance/host/15-load-packs-engine-views/note.mk.md +9 -0
- package/dist/conformance/host/15-load-packs-engine-views/scenario.json +10 -0
- package/dist/conformance/host/16-pack-trust/expected.json +37 -0
- package/dist/conformance/host/16-pack-trust/files/ana-1.0.0/pack.json +12 -0
- package/dist/conformance/host/16-pack-trust/files/ana-1.0.0/webview.js +1 -0
- package/dist/conformance/host/16-pack-trust/files/sneaky-1.0.0/pack.json +12 -0
- package/dist/conformance/host/16-pack-trust/files/sneaky-1.0.0/webview.js +1 -0
- package/dist/conformance/host/16-pack-trust/note.mk.md +5 -0
- package/dist/conformance/host/16-pack-trust/scenario.json +26 -0
- package/dist/conformance/host/README.md +221 -0
- package/dist/conformance.d.ts +2 -0
- package/dist/conformance.js +5 -0
- package/dist/diagnostics/render-diagnostics.d.ts +41 -0
- package/dist/diagnostics/render-diagnostics.js +46 -0
- package/dist/export/cascade.d.ts +98 -0
- package/dist/export/cascade.js +159 -0
- package/dist/export/export-zip.d.ts +19 -0
- package/dist/export/export-zip.js +38 -0
- package/dist/export/image-embed.d.ts +126 -0
- package/dist/export/image-embed.js +274 -0
- package/dist/export/note-export.d.ts +332 -0
- package/dist/export/note-export.js +366 -0
- package/dist/export/note-links.d.ts +83 -0
- package/dist/export/note-links.js +241 -0
- package/dist/glue.wasm +0 -0
- package/dist/host/adapter.d.ts +223 -0
- package/dist/host/adapter.js +9 -0
- package/dist/host/cascade-export-behavior.d.ts +120 -0
- package/dist/host/cascade-export-behavior.js +151 -0
- package/dist/host/conformance-runner.d.ts +156 -0
- package/dist/host/conformance-runner.js +634 -0
- package/dist/host/create-host.d.ts +253 -0
- package/dist/host/create-host.js +329 -0
- package/dist/host/editor-behavior.d.ts +157 -0
- package/dist/host/editor-behavior.js +227 -0
- package/dist/host/export/md-plain.d.ts +15 -0
- package/dist/host/export/md-plain.js +125 -0
- package/dist/host/export-behavior.d.ts +113 -0
- package/dist/host/export-behavior.js +257 -0
- package/dist/host/labels.d.ts +24 -0
- package/dist/host/labels.js +32 -0
- package/dist/host/pack-archive.d.ts +30 -0
- package/dist/host/pack-archive.js +68 -0
- package/dist/host/pack-install.d.ts +88 -0
- package/dist/host/pack-install.js +189 -0
- package/dist/host/pack-load.d.ts +72 -0
- package/dist/host/pack-load.js +57 -0
- package/dist/host/pack-remove.d.ts +21 -0
- package/dist/host/pack-remove.js +65 -0
- package/dist/host/pack-trust-behavior.d.ts +79 -0
- package/dist/host/pack-trust-behavior.js +262 -0
- package/dist/host/refresh-interval.d.ts +39 -0
- package/dist/host/refresh-interval.js +61 -0
- package/dist/host/run-behavior.d.ts +89 -0
- package/dist/host/run-behavior.js +168 -0
- package/dist/host/run-diagnostics.d.ts +26 -0
- package/dist/host/run-diagnostics.js +43 -0
- package/dist/host/script-execution.d.ts +72 -0
- package/dist/host/script-execution.js +68 -0
- package/dist/host/terminal-packs.d.ts +39 -0
- package/dist/host/terminal-packs.js +51 -0
- package/dist/html-engine.d.ts +2 -0
- package/dist/html-engine.js +29 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +70 -0
- package/dist/insert/component-catalog.d.ts +23 -0
- package/dist/insert/component-catalog.js +96 -0
- package/dist/node-fs.d.ts +14 -0
- package/dist/node-fs.js +70 -0
- package/dist/node.d.ts +5 -0
- package/dist/node.js +13 -0
- package/dist/package.json +3 -0
- package/dist/packs/discover.d.ts +119 -0
- package/dist/packs/discover.js +266 -0
- package/dist/packs/pack-diagnostics.d.ts +81 -0
- package/dist/packs/pack-diagnostics.js +105 -0
- package/dist/packs/pack-paths.d.ts +53 -0
- package/dist/packs/pack-paths.js +106 -0
- package/dist/packs/pack-render-registry.d.ts +83 -0
- package/dist/packs/pack-render-registry.js +182 -0
- package/dist/packs/pack-scripts.d.ts +20 -0
- package/dist/packs/pack-scripts.js +96 -0
- package/dist/packs/pack-trust.d.ts +57 -0
- package/dist/packs/pack-trust.js +111 -0
- package/dist/packs/prebuilt.d.ts +49 -0
- package/dist/packs/prebuilt.js +97 -0
- package/dist/path-util.d.ts +24 -0
- package/dist/path-util.js +82 -0
- package/dist/run/browser-isolate.d.ts +45 -0
- package/dist/run/browser-isolate.js +81 -0
- package/dist/run/bundle-document.d.ts +29 -0
- package/dist/run/bundle-document.js +40 -0
- package/dist/run/bundle-run.d.ts +188 -0
- package/dist/run/bundle-run.js +232 -0
- package/dist/run/grant-flow.d.ts +232 -0
- package/dist/run/grant-flow.js +390 -0
- package/dist/run/ip-address.d.ts +41 -0
- package/dist/run/ip-address.js +255 -0
- package/dist/run/isolate.d.ts +57 -0
- package/dist/run/isolate.js +22 -0
- package/dist/run/lua-resolver.d.ts +21 -0
- package/dist/run/lua-resolver.js +63 -0
- package/dist/run/net-bridge-worker.d.ts +26 -0
- package/dist/run/net-bridge-worker.js +66 -0
- package/dist/run/net-bridge.d.ts +56 -0
- package/dist/run/net-bridge.js +59 -0
- package/dist/run/net-pinning.d.ts +82 -0
- package/dist/run/net-pinning.js +137 -0
- package/dist/run/net-provider.d.ts +70 -0
- package/dist/run/net-provider.js +289 -0
- package/dist/run/node-isolate.d.ts +30 -0
- package/dist/run/node-isolate.js +117 -0
- package/dist/run/run-flow.d.ts +187 -0
- package/dist/run/run-flow.js +323 -0
- package/dist/run/run-host.d.ts +107 -0
- package/dist/run/run-host.js +241 -0
- package/dist/run/run-job.d.ts +130 -0
- package/dist/run/run-job.js +279 -0
- package/dist/run/run-progress.d.ts +55 -0
- package/dist/run/run-progress.js +42 -0
- package/dist/run/run-trace.d.ts +44 -0
- package/dist/run/run-trace.js +36 -0
- package/dist/run/script-requirements.d.ts +98 -0
- package/dist/run/script-requirements.js +212 -0
- package/dist/run/snapshot-storage.d.ts +25 -0
- package/dist/run/snapshot-storage.js +31 -0
- package/dist/run/stale-values.d.ts +25 -0
- package/dist/run/stale-values.js +32 -0
- package/dist/run/worker-entry-browser.d.ts +42 -0
- package/dist/run/worker-entry-browser.js +77 -0
- package/dist/run/worker-entry.d.ts +1 -0
- package/dist/run/worker-entry.js +96 -0
- package/dist/values-failure.d.ts +17 -0
- package/dist/values-failure.js +1 -0
- package/dist/values-merge.d.ts +39 -0
- package/dist/values-merge.js +33 -0
- package/package.json +77 -4
package/dist/node-fs.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Node-backed implementations of the file-system seams the
|
|
3
|
+
* environment-free half of this package injects: pack discovery's file
|
|
4
|
+
* reader and directory lister, the pack-scripts reader, and the `.mkp`
|
|
5
|
+
* extraction filesystem. Reached only through `@markii/host/node`; nothing
|
|
6
|
+
* in the main entry imports this module.
|
|
7
|
+
*/
|
|
8
|
+
import { mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises';
|
|
9
|
+
/** The real, Node-backed `PackDirectoryLister`. Never rejects: an unreadable, missing or non-directory path resolves `[]`. */
|
|
10
|
+
export function createNodeDirectoryLister() {
|
|
11
|
+
return async (absoluteDir) => {
|
|
12
|
+
try {
|
|
13
|
+
const entries = await readdir(absoluteDir, { withFileTypes: true });
|
|
14
|
+
return entries.map((entry) => ({
|
|
15
|
+
name: entry.name,
|
|
16
|
+
isDirectory: entry.isDirectory(),
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** The real, Node-backed `PackFileReader`. Never rejects: an unreadable or missing path resolves `undefined`. */
|
|
25
|
+
export function createNodeFileReader() {
|
|
26
|
+
return async (absolutePath) => {
|
|
27
|
+
try {
|
|
28
|
+
return await readFile(absolutePath, 'utf8');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** The real, Node-backed `PackScriptsReader`. */
|
|
36
|
+
export function createNodeReader() {
|
|
37
|
+
const listDirectory = createNodeDirectoryLister();
|
|
38
|
+
const readText = createNodeFileReader();
|
|
39
|
+
return {
|
|
40
|
+
readDirectory: (absoluteDir) => listDirectory(absoluteDir),
|
|
41
|
+
readFile: (absolutePath) => readText(absolutePath),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** The real, Node-backed `ArchiveExtractFs`. */
|
|
45
|
+
export function createNodeArchiveExtractFs() {
|
|
46
|
+
return {
|
|
47
|
+
removeDirectory: async (absolutePath) => {
|
|
48
|
+
try {
|
|
49
|
+
await rm(absolutePath, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Quiet: the write that follows fails loudly on its own if the
|
|
53
|
+
// path is genuinely unusable.
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
makeDirectory: async (absolutePath) => {
|
|
57
|
+
await mkdir(absolutePath, { recursive: true });
|
|
58
|
+
},
|
|
59
|
+
writeFile: async (absolutePath, bytes) => {
|
|
60
|
+
await writeFile(absolutePath, bytes);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Pack discovery's reads over the real file system. */
|
|
65
|
+
export function createNodePackDiscoveryIo() {
|
|
66
|
+
return {
|
|
67
|
+
readFile: createNodeFileReader(),
|
|
68
|
+
listDirectory: createNodeDirectoryLister(),
|
|
69
|
+
};
|
|
70
|
+
}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { SpawnRunOptions } from './run/run-host.js';
|
|
2
|
+
export { defaultWorkerPath, spawnRunInThread, workerThreadIsolate, } from './run/node-isolate.js';
|
|
3
|
+
export { createNetProvider } from './run/net-provider.js';
|
|
4
|
+
export { createNodeArchiveExtractFs, createNodeDirectoryLister, createNodeFileReader, createNodePackDiscoveryIo, createNodeReader as createNodePackScriptsReader, } from './node-fs.js';
|
|
5
|
+
export { createHtmlExportEngine } from './html-engine.js';
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @markii/host/node: the half of this package that needs Node, or that
|
|
2
|
+
// carries a heavy engine dependency the main entry must not.
|
|
3
|
+
//
|
|
4
|
+
// The main entry (`./index.ts`) is environment-neutral. This entry adds:
|
|
5
|
+
// - the worker_threads isolate and the pinned network provider (`node:*`);
|
|
6
|
+
// - the Node-backed file-system seams the neutral code takes by injection;
|
|
7
|
+
// - the `@markii/html`-backed static export engine;
|
|
8
|
+
//
|
|
9
|
+
// A Node host imports from both entries. No browser bundle imports this one.
|
|
10
|
+
export { defaultWorkerPath, spawnRunInThread, workerThreadIsolate, } from './run/node-isolate.js';
|
|
11
|
+
export { createNetProvider } from './run/net-provider.js';
|
|
12
|
+
export { createNodeArchiveExtractFs, createNodeDirectoryLister, createNodeFileReader, createNodePackDiscoveryIo, createNodeReader as createNodePackScriptsReader, } from './node-fs.js';
|
|
13
|
+
export { createHtmlExportEngine } from './html-engine.js';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { PackManifest } from '@markii/pack';
|
|
2
|
+
import type { UnavailableComponent } from '@markii/stdlib';
|
|
3
|
+
/**
|
|
4
|
+
* What a valid pack that declares nothing for this host's engine carries on
|
|
5
|
+
* its skipped entry: its namespace, and every component it declares with
|
|
6
|
+
* the engines each one does ship a view for, so a note that uses one can say
|
|
7
|
+
* "no view here" rather than "unknown component".
|
|
8
|
+
*/
|
|
9
|
+
export interface EngineUnsupportedPack {
|
|
10
|
+
readonly packName: string;
|
|
11
|
+
readonly components: readonly UnavailableComponent[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Every component a pack declares, as `{ directive, pack, engines }` with
|
|
15
|
+
* the engine ids sorted. The shape a host hands a renderer's
|
|
16
|
+
* `unavailableComponents` option after filtering.
|
|
17
|
+
*/
|
|
18
|
+
export declare function declaredPackComponents(manifest: Pick<PackManifest, 'name' | 'components' | 'engine'>): UnavailableComponent[];
|
|
19
|
+
/** The components, from `declared`, that ship no view for `engine`. */
|
|
20
|
+
export declare function componentsWithoutEngineView(declared: readonly UnavailableComponent[], engine: string): UnavailableComponent[];
|
|
21
|
+
/** Reads a file's UTF-8 text, or resolves `undefined` if it does not exist / cannot be read. Never rejects for an ordinary "not found" — injected so this module needs no real filesystem to test. */
|
|
22
|
+
export type PackFileReader = (absolutePath: string) => Promise<string | undefined>;
|
|
23
|
+
/** Lists one directory's immediate entries, or `[]` if it does not exist / cannot be read / is not a directory. Never rejects — injected (like `PackFileReader`) so the one-level parent-folder scan below is testable without real disk. */
|
|
24
|
+
export type PackDirectoryLister = (absoluteDir: string) => Promise<ReadonlyArray<{
|
|
25
|
+
name: string;
|
|
26
|
+
isDirectory: boolean;
|
|
27
|
+
}>>;
|
|
28
|
+
/** One successfully discovered, validated pack. */
|
|
29
|
+
export interface DiscoveredPack {
|
|
30
|
+
/** The configured folder this pack was discovered in (absolute path, as given). */
|
|
31
|
+
readonly folder: string;
|
|
32
|
+
readonly manifest: PackManifest;
|
|
33
|
+
/** Local component name -> absolute path to its declared source file (`manifest.components[name]`, resolved against `folder`). Informational: what a host consumes them for (bundling, `import()`, or locating the pack's prebuilt registration script) is that host's own concern. */
|
|
34
|
+
readonly componentPaths: Readonly<Record<string, string>>;
|
|
35
|
+
/** Engine id -> (local component name -> absolute source path), for every engine any component declares a source for. `componentPaths` is the `react` slice of this. A terminal build (`ansi`) reads its slice here. */
|
|
36
|
+
readonly componentPathsByEngine?: Readonly<Record<string, Readonly<Record<string, string>>>>;
|
|
37
|
+
/** Absolute path to this pack's `scripts/` directory (docs/packs.md: shared Lua modules travel here). The directory need not actually exist — a pack with no shared Lua simply has nothing under it. */
|
|
38
|
+
readonly scriptsDir: string;
|
|
39
|
+
/**
|
|
40
|
+
* Absolute path to this pack's prebuilt registration script (`webview.js`,
|
|
41
|
+
* sibling to `pack.json`) — a HOST-SPECIFIC CONVENTION layered on top of
|
|
42
|
+
* the neutral pack contract (`@markii/pack`'s `PackManifest.components`
|
|
43
|
+
* only names pack-relative SOURCE paths for a bundler, per
|
|
44
|
+
* docs/packs.md; it says nothing about a prebuilt browser artifact).
|
|
45
|
+
* Named `scriptPath`, not `webviewScriptPath`: this field is read by
|
|
46
|
+
* every host that loads a pack's compiled registration script, not only
|
|
47
|
+
* a host with an actual webview (e.g. an Obsidian plugin evaluates it
|
|
48
|
+
* in-process — see that host's `pack-runtime.ts`), and this package has
|
|
49
|
+
* no webview of its own. The on-disk filename convention (`webview.js`)
|
|
50
|
+
* is unchanged — a script authored for one host still works for another,
|
|
51
|
+
* since the compiled-artifact contract itself
|
|
52
|
+
* (`window.__markiiRegisterPack`/lazy `window.__markiiReact`) is
|
|
53
|
+
* host-neutral (see `./pack-build.ts`'s top doc comment). The file need
|
|
54
|
+
* not actually exist — a pack with no such script simply never
|
|
55
|
+
* contributes anything to a host's registry, and every directive under
|
|
56
|
+
* its namespace falls through to the standard unknown-component
|
|
57
|
+
* fallback (the same engine-gating posture `@markii/react`'s `loadPack`
|
|
58
|
+
* already takes for an unsupported `engine`).
|
|
59
|
+
*/
|
|
60
|
+
readonly scriptPath: string;
|
|
61
|
+
/**
|
|
62
|
+
* Absolute path to this pack's emitted stylesheet, when one exists — a
|
|
63
|
+
* SIBLING of `scriptPath`'s compiled output (`./pack-build.ts`, same
|
|
64
|
+
* cache directory, same content-hash base name, `.css` in place of
|
|
65
|
+
* `.js`). `undefined` here always: discovery itself never scans for one,
|
|
66
|
+
* only a host's own pack-context composition knows whether a build
|
|
67
|
+
* actually produced a stylesheet — it overrides this field on the
|
|
68
|
+
* `DiscoveredPack` copy it uses once `buildPackRegistrationScript`'s
|
|
69
|
+
* outcome carries a `stylesheetPath`. A pack that ships its own prebuilt
|
|
70
|
+
* `webview.js` (no compile step at all) has no established
|
|
71
|
+
* sibling-stylesheet convention and never gets one here either.
|
|
72
|
+
*/
|
|
73
|
+
readonly stylesheetPath?: string;
|
|
74
|
+
}
|
|
75
|
+
/** One folder that did not produce a usable pack, and why — developer-facing only, never shown as page content. */
|
|
76
|
+
export interface SkippedPackFolder {
|
|
77
|
+
readonly folder: string;
|
|
78
|
+
readonly reason: string;
|
|
79
|
+
/** Set when the pack is valid but declares nothing for this host's renderer engine (an expected state, not a failure). `packName` is its namespace. */
|
|
80
|
+
readonly engineUnsupported?: EngineUnsupportedPack;
|
|
81
|
+
}
|
|
82
|
+
export interface DiscoverPacksResult {
|
|
83
|
+
/** Every pack that validated AND whose namespace does not collide with another discovered pack. Empty when every configured folder was invalid or every valid pack collided. */
|
|
84
|
+
readonly packs: readonly DiscoveredPack[];
|
|
85
|
+
/** Namespaces that appeared more than once across the configured folders (docs/packs.md: "Installing two packs with the same namespace is rejected at install time") — every pack sharing a colliding namespace is excluded from `packs`, not just the second one, so install stays all-or-nothing per namespace. */
|
|
86
|
+
readonly collisions: readonly string[];
|
|
87
|
+
/** Folders that produced no pack, with a short reason each (missing/unreadable `pack.json`, malformed JSON, failed manifest validation). */
|
|
88
|
+
readonly skipped: readonly SkippedPackFolder[];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Discovers and validates a pack in each of `folders`, in order, then
|
|
92
|
+
* removes (and reports via `collisions`) every pack whose namespace repeats
|
|
93
|
+
* across the set. Duplicate folder entries in `folders` collapse to one
|
|
94
|
+
* discovery attempt each (`Set`), so a repeated setting entry can never
|
|
95
|
+
* itself manufacture a spurious collision.
|
|
96
|
+
*
|
|
97
|
+
* `supportedEngine`, when given, additionally skips (rather than
|
|
98
|
+
* discovers) any pack whose manifest names a different `engine` — see
|
|
99
|
+
* `checkEngine`. Omitted (the default), a pack's engine is not checked
|
|
100
|
+
* here at all, matching this function's behavior before this parameter
|
|
101
|
+
* existed; a caller that only lists packs for a purpose engine-agnostic
|
|
102
|
+
* (e.g. `@markii/pack`'s own tooling) is unaffected.
|
|
103
|
+
*
|
|
104
|
+
* ONE-LEVEL PARENT-FOLDER SCAN: when a configured folder has no `pack.json`
|
|
105
|
+
* of its own (not "has one that fails validation" — see `ManifestAttempt`'s
|
|
106
|
+
* doc comment), its immediate subfolders are probed the same way, and each
|
|
107
|
+
* one that DOES have a valid `pack.json` counts as its own discovered pack
|
|
108
|
+
* (`folder` set to the child path). This lets a user configure one parent
|
|
109
|
+
* (`packs`) that holds several pack folders (`packs/pack1`, `packs/pack2`)
|
|
110
|
+
* instead of listing each one in the host's setting. Exactly one level
|
|
111
|
+
* deep, never recursive: a grandchild's `pack.json` is never found this
|
|
112
|
+
* way. A parent with neither its own manifest nor any child manifest is
|
|
113
|
+
* skipped exactly as before ("no readable pack.json"), and a child that
|
|
114
|
+
* DOES have a `pack.json` but fails validation is skipped individually, by
|
|
115
|
+
* its own (child) folder path.
|
|
116
|
+
*/
|
|
117
|
+
export declare function discoverPacks(folders: readonly string[], readFile: PackFileReader, listDirectory: PackDirectoryLister, supportedEngine?: string): Promise<DiscoverPacksResult>;
|
|
118
|
+
/** The discovered packs' namespaces — what `resolveUses` (`@markii/pack`) checks a note's `uses:` declaration against. */
|
|
119
|
+
export declare function installedNamespaces(packs: readonly DiscoveredPack[]): string[];
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-side, host-UI-free discovery of installed component packs
|
|
3
|
+
* (docs/packs.md, GitHub issue #3 slice 5). Given the folders named by a
|
|
4
|
+
* host's own pack-folder setting (VS Code's `markii.packs`, this plugin's
|
|
5
|
+
* device-local pack-folder list, or any future host's equivalent), reads
|
|
6
|
+
* each folder's `pack.json`, validates it with `@markii/pack`'s
|
|
7
|
+
* `parsePackManifest`, and returns a model of what was found: the manifest
|
|
8
|
+
* plus absolute, host-resolved paths to the pack-relative locations a
|
|
9
|
+
* later step needs (each component's declared source, and the pack's
|
|
10
|
+
* `scripts/` directory for shared Lua modules).
|
|
11
|
+
*
|
|
12
|
+
* Lives in `@markii/host` (not any one app) because it is pure logic over
|
|
13
|
+
* paths, manifests, and strings — no `vscode`, no `obsidian`, no React, and
|
|
14
|
+
* no knowledge of which host is calling it. `apps/vscode/src/packs/`'s
|
|
15
|
+
* `apps/obsidian/src/packs/` copies of this file (pre-dating this hoist)
|
|
16
|
+
* differed only in the field names below (`scriptPath`/`stylesheetPath` —
|
|
17
|
+
* see those fields' own doc comments for why the neutral names won).
|
|
18
|
+
*
|
|
19
|
+
* Filesystem access is injected (`readFile`) rather than imported directly,
|
|
20
|
+
* so this whole module is testable with plain in-memory fakes.
|
|
21
|
+
*
|
|
22
|
+
* Cleanliness (AGENTS.md): a folder with no `pack.json`, malformed JSON, or
|
|
23
|
+
* a manifest that fails validation is QUIETLY skipped — never a thrown
|
|
24
|
+
* error or a dump in the UI. A caller that wants to surface *why* a pack
|
|
25
|
+
* failed to load can read `DiscoverPacksResult.skipped`, which is optional,
|
|
26
|
+
* developer-facing detail (a host's own diagnostics surface), never
|
|
27
|
+
* something shown as page content.
|
|
28
|
+
*/
|
|
29
|
+
import { joinPath } from '../path-util.js';
|
|
30
|
+
import { parsePackManifest } from '@markii/pack';
|
|
31
|
+
import { composeDirectiveName, detectNamespaceCollisions, packComponents, packComponentsForEngine, packDeclaredEngines, packSupportsEngine, } from '@markii/pack';
|
|
32
|
+
/**
|
|
33
|
+
* Every component a pack declares, as `{ directive, pack, engines }` with
|
|
34
|
+
* the engine ids sorted. The shape a host hands a renderer's
|
|
35
|
+
* `unavailableComponents` option after filtering.
|
|
36
|
+
*/
|
|
37
|
+
export function declaredPackComponents(manifest) {
|
|
38
|
+
const declared = [];
|
|
39
|
+
for (const listing of packComponents(manifest)) {
|
|
40
|
+
const composed = composeDirectiveName(manifest.name, listing.localName);
|
|
41
|
+
if (!composed.ok)
|
|
42
|
+
continue;
|
|
43
|
+
declared.push({
|
|
44
|
+
directive: composed.name,
|
|
45
|
+
pack: manifest.name,
|
|
46
|
+
engines: Object.keys(listing.sources).sort(),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return declared;
|
|
50
|
+
}
|
|
51
|
+
/** The components, from `declared`, that ship no view for `engine`. */
|
|
52
|
+
export function componentsWithoutEngineView(declared, engine) {
|
|
53
|
+
return declared.filter((component) => !component.engines.includes(engine));
|
|
54
|
+
}
|
|
55
|
+
/** A sane upper bound on how many immediate children of one configured folder the one-level parent-folder scan (`discoverPacks`) will probe for a `pack.json` — defense in depth against a pathological folder (thousands of entries, a symlink farm) turning "load the installed packs" into an unbounded scan. Matches the spirit of `./pack-scripts.ts`'s `MAX_SCRIPT_FILES_PER_PACK`. */
|
|
56
|
+
const MAX_CHILD_FOLDERS_PER_PARENT = 200;
|
|
57
|
+
/**
|
|
58
|
+
* The engine whose source paths fill `DiscoveredPack.componentPaths`. A
|
|
59
|
+
* data-field name from the pack contract, not a renderer dependency.
|
|
60
|
+
*/
|
|
61
|
+
const COMPONENT_PATHS_ENGINE = 'react';
|
|
62
|
+
/** `folder`/`pack.json`, joined with the host path separator. */
|
|
63
|
+
function manifestPathFor(folder) {
|
|
64
|
+
return joinPath(folder, 'pack.json');
|
|
65
|
+
}
|
|
66
|
+
async function tryLoadPackAt(folder, readFile) {
|
|
67
|
+
const manifestPath = manifestPathFor(folder);
|
|
68
|
+
let text;
|
|
69
|
+
try {
|
|
70
|
+
text = await readFile(manifestPath);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
text = undefined;
|
|
74
|
+
}
|
|
75
|
+
if (text === undefined) {
|
|
76
|
+
return { kind: 'missing' };
|
|
77
|
+
}
|
|
78
|
+
const result = parsePackManifest(text);
|
|
79
|
+
if (!result.ok) {
|
|
80
|
+
return {
|
|
81
|
+
kind: 'invalid',
|
|
82
|
+
reason: `invalid pack.json (${result.errors.join('; ')})`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Read the manifest's components map only through @markii/pack's
|
|
86
|
+
// packComponents() — the one accessor that normalizes both the string
|
|
87
|
+
// shorthand and the object form (source/description/kind), so this
|
|
88
|
+
// module never re-implements that walk or its Object.hasOwn guarding.
|
|
89
|
+
const componentPaths = {};
|
|
90
|
+
for (const listing of packComponentsForEngine(result.manifest, COMPONENT_PATHS_ENGINE)) {
|
|
91
|
+
componentPaths[listing.localName] = joinPath(folder, listing.source);
|
|
92
|
+
}
|
|
93
|
+
const componentPathsByEngine = {};
|
|
94
|
+
for (const listing of packComponents(result.manifest)) {
|
|
95
|
+
for (const [engine, source] of Object.entries(listing.sources)) {
|
|
96
|
+
const slice = (componentPathsByEngine[engine] ??= {});
|
|
97
|
+
slice[listing.localName] = joinPath(folder, source);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
kind: 'found',
|
|
102
|
+
pack: {
|
|
103
|
+
folder,
|
|
104
|
+
manifest: result.manifest,
|
|
105
|
+
componentPaths,
|
|
106
|
+
componentPathsByEngine,
|
|
107
|
+
scriptsDir: joinPath(folder, 'scripts'),
|
|
108
|
+
scriptPath: joinPath(folder, 'webview.js'),
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Discovers and validates a pack in each of `folders`, in order, then
|
|
114
|
+
* removes (and reports via `collisions`) every pack whose namespace repeats
|
|
115
|
+
* across the set. Duplicate folder entries in `folders` collapse to one
|
|
116
|
+
* discovery attempt each (`Set`), so a repeated setting entry can never
|
|
117
|
+
* itself manufacture a spurious collision.
|
|
118
|
+
*
|
|
119
|
+
* ONE-LEVEL PARENT-FOLDER SCAN: when a configured folder has no `pack.json`
|
|
120
|
+
* of its own (not "has one that fails validation" — see `ManifestAttempt`'s
|
|
121
|
+
* doc comment), its immediate subfolders are probed the same way, and each
|
|
122
|
+
* one that DOES have a valid `pack.json` counts as its own discovered pack
|
|
123
|
+
* (`folder` set to the child path). This lets a user configure one parent
|
|
124
|
+
* (`packs`) that holds several pack folders (`packs/pack1`, `packs/pack2`)
|
|
125
|
+
* instead of listing each one in the host's setting. Exactly one level
|
|
126
|
+
* deep, never recursive: a grandchild's `pack.json` is never found this
|
|
127
|
+
* way. A parent with neither its own manifest nor any child manifest is
|
|
128
|
+
* skipped exactly as before ("no readable pack.json"), and a child that
|
|
129
|
+
* DOES have a `pack.json` but fails validation is skipped individually, by
|
|
130
|
+
* its own (child) folder path.
|
|
131
|
+
*/
|
|
132
|
+
/**
|
|
133
|
+
* When a `ManifestAttempt` succeeded (`kind: 'found'`) but the manifest's
|
|
134
|
+
* `engine` does not match `supportedEngine` (batch 7 #46), downgrades it to
|
|
135
|
+
* a `SkippedPackFolder` instead of a `DiscoveredPack` — same effect
|
|
136
|
+
* `@markii/react`'s `loadPack` already has for an unsupported engine
|
|
137
|
+
* (nothing registered for that namespace, unknown-component fallback for
|
|
138
|
+
* every directive under it), but recorded here too so it also drops out of
|
|
139
|
+
* a host's Insert Component / completion catalog (`discoverConfiguredPacks`
|
|
140
|
+
* consumers) instead of offering a snippet for a component nothing can
|
|
141
|
+
* ever render, and so the skip reaches the SAME diagnostics line every
|
|
142
|
+
* other skip does — never silent.
|
|
143
|
+
*/
|
|
144
|
+
function checkEngine(pack, supportedEngine) {
|
|
145
|
+
if (supportedEngine === undefined ||
|
|
146
|
+
packSupportsEngine(pack.manifest, supportedEngine)) {
|
|
147
|
+
return { kind: 'found', pack };
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
kind: 'invalid',
|
|
151
|
+
reason: `pack engine "${packDeclaredEngines(pack.manifest)}" is not supported here (expected "${supportedEngine}"); its components fall back to the unknown-component box`,
|
|
152
|
+
engineUnsupported: {
|
|
153
|
+
packName: pack.manifest.name,
|
|
154
|
+
components: declaredPackComponents(pack.manifest),
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Discovers and validates a pack in each of `folders`, in order, then
|
|
160
|
+
* removes (and reports via `collisions`) every pack whose namespace repeats
|
|
161
|
+
* across the set. Duplicate folder entries in `folders` collapse to one
|
|
162
|
+
* discovery attempt each (`Set`), so a repeated setting entry can never
|
|
163
|
+
* itself manufacture a spurious collision.
|
|
164
|
+
*
|
|
165
|
+
* `supportedEngine`, when given, additionally skips (rather than
|
|
166
|
+
* discovers) any pack whose manifest names a different `engine` — see
|
|
167
|
+
* `checkEngine`. Omitted (the default), a pack's engine is not checked
|
|
168
|
+
* here at all, matching this function's behavior before this parameter
|
|
169
|
+
* existed; a caller that only lists packs for a purpose engine-agnostic
|
|
170
|
+
* (e.g. `@markii/pack`'s own tooling) is unaffected.
|
|
171
|
+
*
|
|
172
|
+
* ONE-LEVEL PARENT-FOLDER SCAN: when a configured folder has no `pack.json`
|
|
173
|
+
* of its own (not "has one that fails validation" — see `ManifestAttempt`'s
|
|
174
|
+
* doc comment), its immediate subfolders are probed the same way, and each
|
|
175
|
+
* one that DOES have a valid `pack.json` counts as its own discovered pack
|
|
176
|
+
* (`folder` set to the child path). This lets a user configure one parent
|
|
177
|
+
* (`packs`) that holds several pack folders (`packs/pack1`, `packs/pack2`)
|
|
178
|
+
* instead of listing each one in the host's setting. Exactly one level
|
|
179
|
+
* deep, never recursive: a grandchild's `pack.json` is never found this
|
|
180
|
+
* way. A parent with neither its own manifest nor any child manifest is
|
|
181
|
+
* skipped exactly as before ("no readable pack.json"), and a child that
|
|
182
|
+
* DOES have a `pack.json` but fails validation is skipped individually, by
|
|
183
|
+
* its own (child) folder path.
|
|
184
|
+
*/
|
|
185
|
+
export async function discoverPacks(folders, readFile, listDirectory, supportedEngine) {
|
|
186
|
+
const uniqueFolders = [...new Set(folders)];
|
|
187
|
+
const found = [];
|
|
188
|
+
const skipped = [];
|
|
189
|
+
for (const folder of uniqueFolders) {
|
|
190
|
+
const rawAttempt = await tryLoadPackAt(folder, readFile);
|
|
191
|
+
const attempt = rawAttempt.kind === 'found'
|
|
192
|
+
? checkEngine(rawAttempt.pack, supportedEngine)
|
|
193
|
+
: rawAttempt;
|
|
194
|
+
if (attempt.kind === 'found') {
|
|
195
|
+
found.push(attempt.pack);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (attempt.kind === 'invalid') {
|
|
199
|
+
skipped.push({
|
|
200
|
+
folder,
|
|
201
|
+
reason: attempt.reason,
|
|
202
|
+
...(attempt.engineUnsupported
|
|
203
|
+
? { engineUnsupported: attempt.engineUnsupported }
|
|
204
|
+
: {}),
|
|
205
|
+
});
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// 'missing': this folder itself has no pack.json — try its immediate
|
|
209
|
+
// children, one level only.
|
|
210
|
+
let entries = [];
|
|
211
|
+
try {
|
|
212
|
+
entries = await listDirectory(folder);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
entries = [];
|
|
216
|
+
}
|
|
217
|
+
let anyChildManifest = false;
|
|
218
|
+
for (const entry of entries.slice(0, MAX_CHILD_FOLDERS_PER_PARENT)) {
|
|
219
|
+
if (!entry.isDirectory)
|
|
220
|
+
continue;
|
|
221
|
+
const childFolder = joinPath(folder, entry.name);
|
|
222
|
+
const rawChildAttempt = await tryLoadPackAt(childFolder, readFile);
|
|
223
|
+
const childAttempt = rawChildAttempt.kind === 'found'
|
|
224
|
+
? checkEngine(rawChildAttempt.pack, supportedEngine)
|
|
225
|
+
: rawChildAttempt;
|
|
226
|
+
if (childAttempt.kind === 'found') {
|
|
227
|
+
found.push(childAttempt.pack);
|
|
228
|
+
anyChildManifest = true;
|
|
229
|
+
}
|
|
230
|
+
else if (childAttempt.kind === 'invalid') {
|
|
231
|
+
skipped.push({
|
|
232
|
+
folder: childFolder,
|
|
233
|
+
reason: childAttempt.reason,
|
|
234
|
+
...(childAttempt.engineUnsupported
|
|
235
|
+
? { engineUnsupported: childAttempt.engineUnsupported }
|
|
236
|
+
: {}),
|
|
237
|
+
});
|
|
238
|
+
anyChildManifest = true;
|
|
239
|
+
}
|
|
240
|
+
// 'missing' for a child: an ordinary non-pack subfolder, not worth
|
|
241
|
+
// reporting individually.
|
|
242
|
+
}
|
|
243
|
+
if (!anyChildManifest) {
|
|
244
|
+
skipped.push({ folder, reason: 'no readable pack.json' });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const collisionNames = new Set(detectNamespaceCollisions(found.map((pack) => pack.manifest.name)).map((collision) => collision.namespace));
|
|
248
|
+
const packs = found.filter((pack) => !collisionNames.has(pack.manifest.name));
|
|
249
|
+
for (const pack of found) {
|
|
250
|
+
if (collisionNames.has(pack.manifest.name)) {
|
|
251
|
+
skipped.push({
|
|
252
|
+
folder: pack.folder,
|
|
253
|
+
reason: `pack namespace "${pack.manifest.name}" collides with another configured pack and was not installed`,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
packs,
|
|
259
|
+
collisions: [...collisionNames],
|
|
260
|
+
skipped,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/** The discovered packs' namespaces — what `resolveUses` (`@markii/pack`) checks a note's `uses:` declaration against. */
|
|
264
|
+
export function installedNamespaces(packs) {
|
|
265
|
+
return packs.map((pack) => pack.manifest.name);
|
|
266
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { PackManifest } from '@markii/pack';
|
|
2
|
+
/** The minimal shape of one loaded pack this module needs — a structural subset of `./discover.ts`'s `DiscoveredPack`. */
|
|
3
|
+
export interface PackDiagnosticsPack {
|
|
4
|
+
readonly manifest: Pick<PackManifest, 'name' | 'engine' | 'components'>;
|
|
5
|
+
}
|
|
6
|
+
/** The minimal shape of one skipped folder this module needs — a structural subset of `./discover.ts`'s `SkippedPackFolder`. */
|
|
7
|
+
export interface PackDiagnosticsSkippedFolder {
|
|
8
|
+
readonly folder: string;
|
|
9
|
+
readonly reason: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PackDiagnosticsContext {
|
|
12
|
+
/** Every validated, non-colliding discovered pack. */
|
|
13
|
+
readonly packs: readonly PackDiagnosticsPack[];
|
|
14
|
+
/** The renderer engine whose components the "Loaded pack" line counts. Absent counts every declared component. */
|
|
15
|
+
readonly engine?: string;
|
|
16
|
+
/** Configured folders that produced no usable pack, and why. */
|
|
17
|
+
readonly skipped: readonly PackDiagnosticsSkippedFolder[];
|
|
18
|
+
/** Already-formatted lines, one per relative pack-folder-setting entry (host-specific wording — see this module's top doc comment). Defaults to none. */
|
|
19
|
+
readonly relativeEntryLines?: readonly string[];
|
|
20
|
+
/** Already-formatted informational lines, one per pack whose prebuilt webview.js shadows component sources on disk (host-specific wording, since each host names its own build command). Informational, never a failure: shipping both is a supported state. */
|
|
21
|
+
readonly prebuiltShadowLines?: readonly string[];
|
|
22
|
+
/** Pack CSS authoring warnings against every built pack's emitted stylesheet. Warnings only, developer-facing. */
|
|
23
|
+
readonly cssWarnings: readonly string[];
|
|
24
|
+
/** One line per malformed pack registration, dropped rather than installed (`./pack-render-registry.ts`'s `BuildRenderRegistryResult.invalidReasons`). Omitted (or empty) contributes nothing — a host that never validates registrations on this side (e.g. VS Code's webview validates them separately, in the browser) simply has none to report yet. */
|
|
25
|
+
readonly invalidRegistrationReasons?: readonly string[];
|
|
26
|
+
/** Namespaces shared by two or more registered packs (`./pack-render-registry.ts`'s `BuildRenderRegistryResult.collisions`). When non-empty, contributes one summary line. */
|
|
27
|
+
readonly registrationCollisions?: readonly string[];
|
|
28
|
+
/** Composed directive names two DIFFERENT packs both claimed (`./pack-render-registry.ts`'s `BuildRenderRegistryResult.duplicateComposedNames`) — the first pack keeps the name, and each entry here names both the pack that kept it and the pack whose component was skipped. Omitted (or empty) contributes nothing; this is expected to stay empty under ordinary pack composition (see that module's doc comment). */
|
|
29
|
+
readonly duplicateComposedNames?: readonly {
|
|
30
|
+
readonly composedName: string;
|
|
31
|
+
readonly keptPack: string;
|
|
32
|
+
readonly skippedPack: string;
|
|
33
|
+
}[];
|
|
34
|
+
/**
|
|
35
|
+
* One entry per validated, non-colliding pack whose declared engine
|
|
36
|
+
* `@markii/react`'s `loadPack` cannot run (`./pack-render-registry.ts`'s
|
|
37
|
+
* `BuildRenderRegistryResult.droppedEngines`, batch 7 #46). Omitted (or
|
|
38
|
+
* empty) contributes nothing — the ordinary case where every registered
|
|
39
|
+
* pack's engine is supported.
|
|
40
|
+
*/
|
|
41
|
+
readonly droppedEngines?: readonly {
|
|
42
|
+
name: string;
|
|
43
|
+
engine: string;
|
|
44
|
+
}[];
|
|
45
|
+
}
|
|
46
|
+
/** The one line for a folder `discoverPacks` could not turn into a usable pack. */
|
|
47
|
+
export declare function skippedPackFolderLine(entry: PackDiagnosticsSkippedFolder): string;
|
|
48
|
+
/**
|
|
49
|
+
* The full set of diagnostic lines for one pack-loading outcome: loaded
|
|
50
|
+
* packs first (the confirmation that the setting is working at all), then
|
|
51
|
+
* every skipped folder with its reason, then relative-entry lines, then
|
|
52
|
+
* prebuilt-shadow lines, then pack CSS lint warnings, then any
|
|
53
|
+
* invalid-registration, namespace-collision, or duplicate-composed-name
|
|
54
|
+
* lines. Empty when nothing is configured at all — the caller decides
|
|
55
|
+
* whether an empty result is worth writing anything to its own
|
|
56
|
+
* diagnostics surface.
|
|
57
|
+
*/
|
|
58
|
+
export declare function formatPackDiagnosticLines(context: PackDiagnosticsContext): string[];
|
|
59
|
+
/** How many configured folders failed to produce a usable pack — what a preview's quiet marker counts. */
|
|
60
|
+
export declare function skippedPackCount(context: {
|
|
61
|
+
readonly skipped: readonly PackDiagnosticsSkippedFolder[];
|
|
62
|
+
}): number;
|
|
63
|
+
/**
|
|
64
|
+
* One informational line for a pack whose prebuilt `webview.js` shadows
|
|
65
|
+
* component sources still present in the same folder — survey finding A9:
|
|
66
|
+
* `apps/vscode/src/packs/pack-diagnostics.ts` and
|
|
67
|
+
* `apps/obsidian/src/packs/pack-diagnostics.ts` each defined this exact
|
|
68
|
+
* sentence shape, differing only in the tail clause naming how a user
|
|
69
|
+
* would rebuild the prebuilt artifact from those sources (VS Code's own
|
|
70
|
+
* Export Pack command versus, from Obsidian, VS Code's Export Pack command
|
|
71
|
+
* by name, since Obsidian has no build command of its own).
|
|
72
|
+
*
|
|
73
|
+
* Never a failure: shipping both the built artifact and its sources is a
|
|
74
|
+
* supported distribution shape. `rebuildInstruction` is the one thing that
|
|
75
|
+
* differs per host — a short clause completing "Edits to them take effect
|
|
76
|
+
* only after you delete webview.js, or ...".
|
|
77
|
+
*/
|
|
78
|
+
export declare function prebuiltShadowLine(pack: {
|
|
79
|
+
readonly name: string;
|
|
80
|
+
readonly folder: string;
|
|
81
|
+
}, rebuildInstruction: string): string;
|