@riebeckite/core 0.0.30 → 0.0.31
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/index.js +42 -29
- package/dist/src/content/content_build_state.d.ts +2 -1
- package/dist/src/content/manifest_hook_cache.d.ts +1 -1
- package/dist/src/plugin/manifest_hooks.d.ts +1 -0
- package/dist/src/types/content_manifest.d.ts +0 -7
- package/dist/src/types/plugin.d.ts +3 -0
- package/dist/src/types/plugin_endpoint.d.ts +2 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -826,7 +826,7 @@ function getFileName(filePath) {
|
|
|
826
826
|
}
|
|
827
827
|
|
|
828
828
|
// src/content/content_build_state.ts
|
|
829
|
-
var CONTENT_BUILD_STATE_VERSION =
|
|
829
|
+
var CONTENT_BUILD_STATE_VERSION = 20;
|
|
830
830
|
var CONTENT_BUILD_STATE_DIRECTORY = ".riebeckite";
|
|
831
831
|
var CONTENT_BUILD_STATE_EXCLUDE = `${CONTENT_BUILD_STATE_DIRECTORY}/**`;
|
|
832
832
|
|
|
@@ -834,8 +834,11 @@ var CONTENT_BUILD_STATE_EXCLUDE = `${CONTENT_BUILD_STATE_DIRECTORY}/**`;
|
|
|
834
834
|
import { randomUUID } from "node:crypto";
|
|
835
835
|
import fs from "node:fs/promises";
|
|
836
836
|
import path from "node:path";
|
|
837
|
+
var MAX_CONTENT_BUILD_STATE_BYTES = 64 * 1024 * 1024;
|
|
837
838
|
async function loadContentBuildState(statePath) {
|
|
838
839
|
try {
|
|
840
|
+
const metadata = await fs.stat(statePath);
|
|
841
|
+
if (metadata.size > MAX_CONTENT_BUILD_STATE_BYTES) return void 0;
|
|
839
842
|
const parsed = JSON.parse(await fs.readFile(statePath, "utf8"));
|
|
840
843
|
return isContentBuildState(parsed) ? parsed : void 0;
|
|
841
844
|
} catch {
|
|
@@ -922,7 +925,7 @@ function isContentBuildStateShape(value) {
|
|
|
922
925
|
}
|
|
923
926
|
function isManifestHookCache(value) {
|
|
924
927
|
return Array.isArray(value) && value.every(
|
|
925
|
-
(entry) => isRecord2(entry) && typeof entry.pluginName === "string" && typeof entry.cacheable === "boolean" && (entry.pipelineFingerprint === void 0 || typeof entry.pipelineFingerprint === "string") && typeof entry.inputFingerprint === "string" && (entry.outputFingerprint === void 0 || typeof entry.outputFingerprint === "string") && (entry.snapshot === void 0 || isManifestHookSnapshot(entry.snapshot))
|
|
928
|
+
(entry) => isRecord2(entry) && typeof entry.pluginName === "string" && typeof entry.cacheVersion === "string" && typeof entry.cacheable === "boolean" && (entry.pipelineFingerprint === void 0 || typeof entry.pipelineFingerprint === "string") && typeof entry.inputFingerprint === "string" && (entry.outputFingerprint === void 0 || typeof entry.outputFingerprint === "string") && (entry.snapshot === void 0 || isManifestHookSnapshot(entry.snapshot))
|
|
926
929
|
);
|
|
927
930
|
}
|
|
928
931
|
function isManifestHookSnapshot(value) {
|
|
@@ -2991,16 +2994,18 @@ function serializeManifestEntries(entries) {
|
|
|
2991
2994
|
serialized.set(entry.slug, JSON.stringify(entry));
|
|
2992
2995
|
return serialized;
|
|
2993
2996
|
}
|
|
2994
|
-
function createManifestHookCacheEntry(pluginName, cacheable, pipelineFingerprint, inputFingerprint, manifest, beforeEntries, afterEntries) {
|
|
2997
|
+
function createManifestHookCacheEntry(pluginName, cacheVersion, cacheable, pipelineFingerprint, inputFingerprint, manifest, beforeEntries, afterEntries) {
|
|
2995
2998
|
if (!cacheable)
|
|
2996
2999
|
return {
|
|
2997
3000
|
pluginName,
|
|
3001
|
+
cacheVersion,
|
|
2998
3002
|
cacheable,
|
|
2999
3003
|
pipelineFingerprint,
|
|
3000
3004
|
inputFingerprint
|
|
3001
3005
|
};
|
|
3002
3006
|
return {
|
|
3003
3007
|
pluginName,
|
|
3008
|
+
cacheVersion,
|
|
3004
3009
|
cacheable,
|
|
3005
3010
|
pipelineFingerprint,
|
|
3006
3011
|
inputFingerprint,
|
|
@@ -3282,9 +3287,10 @@ var ManifestHookRunner = class {
|
|
|
3282
3287
|
if (plugin.buildEnd) return "plugin-build-end";
|
|
3283
3288
|
if (plugin.planGeneratedOutputs) return "plugin-generated-output-plan";
|
|
3284
3289
|
if (!plugin.onManifestCreated) continue;
|
|
3290
|
+
if (!plugin.manifestHookCache) return "manifest-hook-cache-disabled";
|
|
3285
3291
|
const cached = previousCache[cacheIndex];
|
|
3286
3292
|
cacheIndex += 1;
|
|
3287
|
-
if (cached?.pluginName !== plugin.name || !cached.cacheable || cached.pipelineFingerprint !== pipelineFingerprint)
|
|
3293
|
+
if (cached?.pluginName !== plugin.name || cached.cacheVersion !== plugin.manifestHookCache.version || !cached.cacheable || cached.pipelineFingerprint !== pipelineFingerprint)
|
|
3288
3294
|
return "manifest-hook-cache-miss";
|
|
3289
3295
|
}
|
|
3290
3296
|
return void 0;
|
|
@@ -3298,10 +3304,14 @@ var ManifestHookRunner = class {
|
|
|
3298
3304
|
manifest
|
|
3299
3305
|
};
|
|
3300
3306
|
let cacheIndex = 0;
|
|
3301
|
-
let entriesBeforeHook = serializeManifestEntries(manifest.entries);
|
|
3302
3307
|
for (const plugin of this.options.plugins()) {
|
|
3303
3308
|
const hook = plugin.onManifestCreated;
|
|
3304
3309
|
if (!hook) continue;
|
|
3310
|
+
const cacheVersion = plugin.manifestHookCache?.version;
|
|
3311
|
+
if (!cacheVersion) {
|
|
3312
|
+
await this.runManifestHook(plugin, hook, context, "cache-disabled");
|
|
3313
|
+
continue;
|
|
3314
|
+
}
|
|
3305
3315
|
const inputFingerprint = fingerprintManifestHookInput(manifest);
|
|
3306
3316
|
const cached = previousCache[cacheIndex];
|
|
3307
3317
|
cacheIndex += 1;
|
|
@@ -3313,46 +3323,29 @@ var ManifestHookRunner = class {
|
|
|
3313
3323
|
);
|
|
3314
3324
|
let restored = false;
|
|
3315
3325
|
let restorePoint;
|
|
3316
|
-
if (cached !== void 0 && cached.pluginName === plugin.name && cached.cacheable && cached.pipelineFingerprint === pipelineFingerprint && cached.inputFingerprint === inputFingerprint && cached.snapshot !== void 0 && cached.outputFingerprint !== void 0) {
|
|
3326
|
+
if (cached !== void 0 && cached.pluginName === plugin.name && cached.cacheVersion === cacheVersion && cached.cacheable && cached.pipelineFingerprint === pipelineFingerprint && cached.inputFingerprint === inputFingerprint && cached.snapshot !== void 0 && cached.outputFingerprint !== void 0) {
|
|
3317
3327
|
restorePoint = captureManifestHookRestorePoint(manifest);
|
|
3318
3328
|
restored = applyManifestHookSnapshot(manifest, cached.snapshot);
|
|
3319
3329
|
if (restored && fingerprintManifestHookSnapshot(manifest) === cached.outputFingerprint) {
|
|
3320
3330
|
this.manifestHooksReused += 1;
|
|
3321
3331
|
this.manifestHookCache.push(cached);
|
|
3322
3332
|
this.recordManifestHookMetric(plugin.name, "reused", "cache-hit", 0);
|
|
3323
|
-
entriesBeforeHook = serializeManifestEntries(manifest.entries);
|
|
3324
3333
|
continue;
|
|
3325
3334
|
}
|
|
3326
3335
|
}
|
|
3327
3336
|
if (restored && restorePoint)
|
|
3328
3337
|
restoreManifestHookEntries(manifest, restorePoint);
|
|
3338
|
+
const entriesBeforeHook = serializeManifestEntries(manifest.entries);
|
|
3329
3339
|
const sideEffectsBefore = fingerprintManifestHookSideEffects(manifest);
|
|
3330
3340
|
const outputCountBefore = this.options.generatedOutputCount();
|
|
3331
3341
|
const diagnosticCountBefore = this.options.diagnosticCount();
|
|
3332
3342
|
const manifestDiagnosticCountBefore = manifest.diagnostics.length;
|
|
3333
|
-
|
|
3334
|
-
this.manifestHooksExecuted += 1;
|
|
3335
|
-
try {
|
|
3336
|
-
await runPluginHook(
|
|
3337
|
-
plugin,
|
|
3338
|
-
"onManifestCreated",
|
|
3339
|
-
this.options.createPluginContext(plugin, context),
|
|
3340
|
-
hook
|
|
3341
|
-
);
|
|
3342
|
-
} finally {
|
|
3343
|
-
const durationMs = performance.now() - started;
|
|
3344
|
-
this.manifestHookDurationMs += durationMs;
|
|
3345
|
-
this.recordManifestHookMetric(
|
|
3346
|
-
plugin.name,
|
|
3347
|
-
"executed",
|
|
3348
|
-
reason,
|
|
3349
|
-
durationMs
|
|
3350
|
-
);
|
|
3351
|
-
}
|
|
3343
|
+
await this.runManifestHook(plugin, hook, context, reason);
|
|
3352
3344
|
const entriesAfterHook = serializeManifestEntries(manifest.entries);
|
|
3353
3345
|
this.manifestHookCache.push(
|
|
3354
3346
|
createManifestHookCacheEntry(
|
|
3355
3347
|
plugin.name,
|
|
3348
|
+
cacheVersion,
|
|
3356
3349
|
plugin.resolveExternalDependencies === void 0 && sideEffectsBefore === fingerprintManifestHookSideEffects(manifest) && outputCountBefore === this.options.generatedOutputCount() && diagnosticCountBefore === this.options.diagnosticCount() && manifestDiagnosticCountBefore === manifest.diagnostics.length,
|
|
3357
3350
|
pipelineFingerprint,
|
|
3358
3351
|
inputFingerprint,
|
|
@@ -3361,7 +3354,27 @@ var ManifestHookRunner = class {
|
|
|
3361
3354
|
entriesAfterHook
|
|
3362
3355
|
)
|
|
3363
3356
|
);
|
|
3364
|
-
|
|
3357
|
+
}
|
|
3358
|
+
}
|
|
3359
|
+
async runManifestHook(plugin, hook, context, reason) {
|
|
3360
|
+
const started = performance.now();
|
|
3361
|
+
this.manifestHooksExecuted += 1;
|
|
3362
|
+
try {
|
|
3363
|
+
await runPluginHook(
|
|
3364
|
+
plugin,
|
|
3365
|
+
"onManifestCreated",
|
|
3366
|
+
this.options.createPluginContext(plugin, context),
|
|
3367
|
+
hook
|
|
3368
|
+
);
|
|
3369
|
+
} finally {
|
|
3370
|
+
const durationMs = performance.now() - started;
|
|
3371
|
+
this.manifestHookDurationMs += durationMs;
|
|
3372
|
+
this.recordManifestHookMetric(
|
|
3373
|
+
plugin.name,
|
|
3374
|
+
"executed",
|
|
3375
|
+
reason,
|
|
3376
|
+
durationMs
|
|
3377
|
+
);
|
|
3365
3378
|
}
|
|
3366
3379
|
}
|
|
3367
3380
|
recordManifestHookMetric(pluginName, outcome, reason, durationMs) {
|
|
@@ -6026,7 +6039,7 @@ var ContentManager = class {
|
|
|
6026
6039
|
/** Resolves a page contributed by an enabled plugin. */
|
|
6027
6040
|
async resolvePage(pathname) {
|
|
6028
6041
|
const [manifest, contentIndex] = await Promise.all([
|
|
6029
|
-
this.getManifest(),
|
|
6042
|
+
this.getManifest({ incremental: false }),
|
|
6030
6043
|
this.getContentIndex()
|
|
6031
6044
|
]);
|
|
6032
6045
|
return await this.pluginRuntime.resolvePage(
|
|
@@ -6089,7 +6102,7 @@ var ContentManager = class {
|
|
|
6089
6102
|
}
|
|
6090
6103
|
requestBuildStateCommit(options) {
|
|
6091
6104
|
if (this.pipelineOptions.commitBuildState === false) return;
|
|
6092
|
-
if (options?.incremental
|
|
6105
|
+
if (options?.incremental !== false) this.buildStateCommitRequested = true;
|
|
6093
6106
|
}
|
|
6094
6107
|
async commitBuildState() {
|
|
6095
6108
|
if (this.buildStateCommitted || !this.buildStateCommitRequested || !this.manifest || !this.outputChangeSet) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ContentManifestEntry } from "../types/content_manifest.js";
|
|
2
2
|
import type { ContentSourceEntry } from "./content_source.js";
|
|
3
3
|
import type { OutputDescriptor } from "./output_dependency.js";
|
|
4
|
-
export declare const CONTENT_BUILD_STATE_VERSION =
|
|
4
|
+
export declare const CONTENT_BUILD_STATE_VERSION = 20;
|
|
5
5
|
/**
|
|
6
6
|
* Build state lives under `<content directory>/.riebeckite`. That directory is
|
|
7
7
|
* build-time state, not content, so content sources must exclude it from scans
|
|
@@ -33,6 +33,7 @@ export type ContentBuildState = {
|
|
|
33
33
|
};
|
|
34
34
|
export type ManifestHookCacheEntry = {
|
|
35
35
|
readonly pluginName: string;
|
|
36
|
+
readonly cacheVersion: string;
|
|
36
37
|
readonly cacheable: boolean;
|
|
37
38
|
readonly pipelineFingerprint: string | undefined;
|
|
38
39
|
readonly inputFingerprint: string;
|
|
@@ -2,7 +2,7 @@ import type { ContentManifest, ContentManifestEntry } from "../types/content_man
|
|
|
2
2
|
import type { ManifestHookCacheEntry, ManifestHookSnapshot } from "./content_build_state.js";
|
|
3
3
|
export declare function fingerprintManifestHookInput(manifest: ContentManifest): string;
|
|
4
4
|
export declare function serializeManifestEntries(entries: readonly ContentManifestEntry[]): Map<string, string>;
|
|
5
|
-
export declare function createManifestHookCacheEntry(pluginName: string, cacheable: boolean, pipelineFingerprint: string | undefined, inputFingerprint: string, manifest: ContentManifest, beforeEntries: ReadonlyMap<string, string>, afterEntries: ReadonlyMap<string, string>): ManifestHookCacheEntry;
|
|
5
|
+
export declare function createManifestHookCacheEntry(pluginName: string, cacheVersion: string, cacheable: boolean, pipelineFingerprint: string | undefined, inputFingerprint: string, manifest: ContentManifest, beforeEntries: ReadonlyMap<string, string>, afterEntries: ReadonlyMap<string, string>): ManifestHookCacheEntry;
|
|
6
6
|
export declare function fingerprintManifestHookSideEffects(manifest: ContentManifest): string;
|
|
7
7
|
export declare function fingerprintManifestHookSnapshot(manifest: ContentManifest): string;
|
|
8
8
|
export type ManifestHookRestorePoint = {
|
|
@@ -37,6 +37,7 @@ export declare class ManifestHookRunner {
|
|
|
37
37
|
getNoChangeFastPathBlockReason(previousCache: readonly ManifestHookCacheEntry[], pipelineFingerprint: string | undefined): string | undefined;
|
|
38
38
|
getCache(): readonly ManifestHookCacheEntry[];
|
|
39
39
|
runManifestCreated(manifest: ContentManifest, contentIndex: Map<string, string>, previousCache: readonly ManifestHookCacheEntry[], pipelineFingerprint: string | undefined): Promise<void>;
|
|
40
|
+
private runManifestHook;
|
|
40
41
|
private recordManifestHookMetric;
|
|
41
42
|
}
|
|
42
43
|
export {};
|
|
@@ -23,13 +23,6 @@ export type ContentAsset = {
|
|
|
23
23
|
export type ContentManifestPluginAsset = PluginAsset & {
|
|
24
24
|
path: string;
|
|
25
25
|
};
|
|
26
|
-
/**
|
|
27
|
-
* The standard `article.*` positions the article consumer recognizes.
|
|
28
|
-
*
|
|
29
|
-
* These constants are a convenience for Sites that prefer named references;
|
|
30
|
-
* writing the slot string inline (for example `name="article.metadata"`) stays
|
|
31
|
-
* the recommended, most readable form in TSX layouts.
|
|
32
|
-
*/
|
|
33
26
|
/** Client entries and their explicitly public configuration. */
|
|
34
27
|
export type ContentManifestPluginClientEntry = PluginClientEntry;
|
|
35
28
|
export type ContentManifestEntry = {
|
|
@@ -74,6 +74,9 @@ export type RiebeckitePlugin<TOptions = unknown> = {
|
|
|
74
74
|
extendContentLocations?(context: PluginContentLocationAugmentContext): void | Promise<void>;
|
|
75
75
|
onPostParsed?(context: PluginPostContext): void | Promise<void>;
|
|
76
76
|
onPostProcessed?(context: PluginPostContext): void | Promise<void>;
|
|
77
|
+
manifestHookCache?: {
|
|
78
|
+
version: string;
|
|
79
|
+
};
|
|
77
80
|
onManifestCreated?(context: PluginManifestContext): void | Promise<void>;
|
|
78
81
|
extendMarkdownPipeline?(pipeline: MarkdownPipeline, context: MarkdownPipelineContext): void;
|
|
79
82
|
extendHtmlPipeline?(pipeline: HtmlPipeline): void;
|
|
@@ -36,6 +36,8 @@ export type PluginEndpoint = {
|
|
|
36
36
|
path: string;
|
|
37
37
|
/** Defaults to `GET` when omitted. */
|
|
38
38
|
method?: PluginEndpointMethod;
|
|
39
|
+
/** Defaults to `true`; set to `false` for endpoints that only use configuration. */
|
|
40
|
+
requiresManifest?: boolean;
|
|
39
41
|
handler(context: PluginEndpointContext): PluginEndpointResponse | Promise<PluginEndpointResponse>;
|
|
40
42
|
};
|
|
41
43
|
export type PluginEndpointOptions = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"tsx": "^4.22.4",
|
|
52
|
-
"@riebeckite/test": "0.0.
|
|
52
|
+
"@riebeckite/test": "0.0.31"
|
|
53
53
|
},
|
|
54
54
|
"repository": {
|
|
55
55
|
"type": "git",
|