@refrakt-md/content 0.14.4 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entity-routes.d.ts +4 -0
- package/dist/entity-routes.d.ts.map +1 -0
- package/dist/entity-routes.js +91 -0
- package/dist/entity-routes.js.map +1 -0
- package/dist/file-roots.d.ts +70 -0
- package/dist/file-roots.d.ts.map +1 -0
- package/dist/file-roots.js +146 -0
- package/dist/file-roots.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +28 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +5 -1
- package/dist/loader.js.map +1 -1
- package/dist/pipeline.d.ts +12 -2
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +74 -7
- package/dist/pipeline.js.map +1 -1
- package/dist/refract-loader.d.ts +14 -1
- package/dist/refract-loader.d.ts.map +1 -1
- package/dist/refract-loader.js +84 -1
- package/dist/refract-loader.js.map +1 -1
- package/dist/registry.d.ts +38 -4
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +157 -23
- package/dist/registry.js.map +1 -1
- package/dist/site.d.ts +25 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +239 -17
- package/dist/site.js.map +1 -1
- package/package.json +5 -5
package/dist/refract-loader.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { SiteConfig, SecurityPolicy } from '@refrakt-md/types';
|
|
1
|
+
import type { SiteConfig, SecurityPolicy, XrefPattern } from '@refrakt-md/types';
|
|
2
|
+
import { type FileRoots } from './file-roots.js';
|
|
2
3
|
import type { ContentTree } from './content-tree.js';
|
|
3
4
|
import type { Site, VirtualReader } from './site.js';
|
|
4
5
|
export interface RefraktLoaderOptions {
|
|
@@ -63,6 +64,18 @@ export interface VirtualRefraktLoaderOptions {
|
|
|
63
64
|
security?: SecurityPolicy;
|
|
64
65
|
/** URL base path for the Router. Default: `'/'`. */
|
|
65
66
|
basePath?: string;
|
|
67
|
+
/** Absolute path to the project root (where `refrakt.config.json` lives, or
|
|
68
|
+
* the conceptual root in a virtual environment). Used to compute
|
|
69
|
+
* `$file.path`. When omitted, `$file.path` falls back to the page's
|
|
70
|
+
* content-root-relative path. */
|
|
71
|
+
projectRoot?: string;
|
|
72
|
+
/** Xref patterns to compile and use as URL-resolution fallback. */
|
|
73
|
+
xrefs?: XrefPattern[];
|
|
74
|
+
/** File roots — namespace → absolute directory path. Hosts that have a
|
|
75
|
+
* conceptual project root should resolve their fileRoots config against
|
|
76
|
+
* it before passing the result here (the virtual loader doesn't read a
|
|
77
|
+
* config file). Plugin-declared roots merge in automatically. */
|
|
78
|
+
fileRoots?: FileRoots;
|
|
66
79
|
/** Skip caching — re-run the pipeline on every load(). Default: false. */
|
|
67
80
|
dev?: boolean;
|
|
68
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refract-loader.d.ts","sourceRoot":"","sources":["../src/refract-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAU,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"refract-loader.d.ts","sourceRoot":"","sources":["../src/refract-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAU,UAAU,EAAE,cAAc,EAAiB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKxG,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAMvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACpC,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;2DACuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC;;;kFAG8E;IAC9E,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,8DAA8D;IAC9D,GAAG,CAAC,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC7B,wDAAwD;IACxD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,yDAAyD;IACzD,YAAY,IAAI,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;IAC5C,8CAA8C;IAC9C,qBAAqB,IAAI,OAAO,CAAC;QAAE,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,uEAAuE;IACvE,cAAc,IAAI,IAAI,CAAC;CACvB;AA6BD;;;;;sDAKsD;AACtD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU;;;;;;EAQrD;AAoHD,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,aAAa,CAoGjF;AAED,MAAM,WAAW,2BAA2B;IAC3C;;;;iFAI6E;IAC7E,IAAI,EAAE,UAAU,CAAC;IACjB;uCACmC;IACnC,IAAI,EAAE,WAAW,CAAC;IAClB;iCAC6B;IAC7B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;sCAGkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB;;;sEAGkE;IAClE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,0EAA0E;IAC1E,GAAG,CAAC,EAAE,OAAO,CAAC;CACd;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG,aAAa,CAmF9F"}
|
package/dist/refract-loader.js
CHANGED
|
@@ -2,7 +2,23 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import { dirname, resolve } from 'node:path';
|
|
3
3
|
import { getThemePackage } from '@refrakt-md/types';
|
|
4
4
|
import { normalizeRefraktConfig, resolveSite, loadPresets } from '@refrakt-md/transform/node';
|
|
5
|
+
import { compileXrefPatterns } from '@refrakt-md/runes';
|
|
6
|
+
import { mergeFileRoots, resolveUserFileRoots } from './file-roots.js';
|
|
5
7
|
import { createSiteLoader, createVirtualSiteLoader, } from './loader.js';
|
|
8
|
+
/** Compile xref patterns from a raw config, logging any diagnostics to
|
|
9
|
+
* stderr so the build surface remains visible. Errors don't throw — they
|
|
10
|
+
* produce a permissively-empty pattern set so the rest of the load
|
|
11
|
+
* succeeds and the user can fix the config without losing the whole site. */
|
|
12
|
+
function compileConfiguredXrefPatterns(patterns) {
|
|
13
|
+
const result = compileXrefPatterns(patterns);
|
|
14
|
+
for (const warning of result.warnings) {
|
|
15
|
+
process.stderr.write(`refrakt: xref pattern warning — ${warning}\n`);
|
|
16
|
+
}
|
|
17
|
+
for (const error of result.errors) {
|
|
18
|
+
process.stderr.write(`refrakt: xref pattern error — ${error}\n`);
|
|
19
|
+
}
|
|
20
|
+
return result.patterns;
|
|
21
|
+
}
|
|
6
22
|
/** Compose the options bag handed to `createHighlightTransform`. Merges the
|
|
7
23
|
* site's `highlight.*` block with theme-level code settings (`theme.code.*`)
|
|
8
24
|
* so a single object reaches the transform — keeps adapter call sites tidy
|
|
@@ -83,6 +99,7 @@ async function assembleSiteContext(site, opts = {}) {
|
|
|
83
99
|
communityTags: undefined,
|
|
84
100
|
communityPackages: undefined,
|
|
85
101
|
icons,
|
|
102
|
+
pluginFileRoots: {},
|
|
86
103
|
};
|
|
87
104
|
}
|
|
88
105
|
const { config: assembledConfig } = assembleThemeConfig({
|
|
@@ -95,6 +112,7 @@ async function assembleSiteContext(site, opts = {}) {
|
|
|
95
112
|
communityTags: undefined,
|
|
96
113
|
communityPackages: undefined,
|
|
97
114
|
icons,
|
|
115
|
+
pluginFileRoots: {},
|
|
98
116
|
};
|
|
99
117
|
}
|
|
100
118
|
const { loadPlugin, mergePlugins, runes: coreRunes } = await import('@refrakt-md/runes');
|
|
@@ -116,6 +134,7 @@ async function assembleSiteContext(site, opts = {}) {
|
|
|
116
134
|
communityTags: Object.keys(merged.tags).length > 0 ? merged.tags : undefined,
|
|
117
135
|
communityPackages: merged.plugins,
|
|
118
136
|
icons,
|
|
137
|
+
pluginFileRoots: merged.fileRoots,
|
|
119
138
|
};
|
|
120
139
|
}
|
|
121
140
|
export function createRefraktLoader(options) {
|
|
@@ -127,6 +146,15 @@ export function createRefraktLoader(options) {
|
|
|
127
146
|
const normalized = normalizeRefraktConfig(rawConfig, { configDir });
|
|
128
147
|
const { site } = resolveSite(normalized, options?.site);
|
|
129
148
|
const contentDir = resolve(site.contentDir);
|
|
149
|
+
// Compile xref patterns once at loader construction. Diagnostics
|
|
150
|
+
// (invalid regex, unknown placeholders, etc.) are surfaced via
|
|
151
|
+
// stderr — adapters can intercept via their own pipeline-warnings
|
|
152
|
+
// formatter once SPEC-058 wiring is fully in place.
|
|
153
|
+
const xrefPatterns = compileConfiguredXrefPatterns(rawConfig.xrefs);
|
|
154
|
+
// Resolve user-config file roots against the config-file directory.
|
|
155
|
+
// Plugin-contributed roots are merged in at init time (after plugins
|
|
156
|
+
// load); user roots win any namespace collision (warning surfaced).
|
|
157
|
+
const userFileRoots = resolveUserFileRoots(rawConfig.fileRoots, configDir);
|
|
130
158
|
let _initPromise = null;
|
|
131
159
|
let _transform = null;
|
|
132
160
|
let _loader = null;
|
|
@@ -137,6 +165,30 @@ export function createRefraktLoader(options) {
|
|
|
137
165
|
_initPromise = (async () => {
|
|
138
166
|
const ctx = await assembleSiteContext(site, { configDir });
|
|
139
167
|
_transform = ctx.transform;
|
|
168
|
+
// Run each plugin's `configure` lifecycle hook before any pipeline
|
|
169
|
+
// phases. Plugins that need build-time config (e.g. plan reading
|
|
170
|
+
// plan.dir for its unconditional-scan path) wire it up here. The
|
|
171
|
+
// `registerFileRoot` callback lets plugins dynamically register
|
|
172
|
+
// file-root namespaces whose paths depend on user config (the
|
|
173
|
+
// plan plugin uses this to expose the user's plan.dir as `plan:`).
|
|
174
|
+
const dynamicFileRoots = {};
|
|
175
|
+
const registerFileRoot = (namespace, absolutePath) => {
|
|
176
|
+
dynamicFileRoots[namespace] = absolutePath;
|
|
177
|
+
};
|
|
178
|
+
for (const pkg of ctx.communityPackages ?? []) {
|
|
179
|
+
if (pkg.pipeline?.configure) {
|
|
180
|
+
await pkg.pipeline.configure({
|
|
181
|
+
config: rawConfig,
|
|
182
|
+
configDir,
|
|
183
|
+
registerFileRoot,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const pluginRoots = { ...ctx.pluginFileRoots, ...dynamicFileRoots };
|
|
188
|
+
const { roots: fileRoots, warnings: fileRootWarnings } = mergeFileRoots(userFileRoots, pluginRoots);
|
|
189
|
+
for (const warning of fileRootWarnings) {
|
|
190
|
+
process.stderr.write(`refrakt: ${warning}\n`);
|
|
191
|
+
}
|
|
140
192
|
_loader = createSiteLoader({
|
|
141
193
|
dirPath: contentDir,
|
|
142
194
|
basePath: '/',
|
|
@@ -145,6 +197,10 @@ export function createRefraktLoader(options) {
|
|
|
145
197
|
plugins: ctx.communityPackages,
|
|
146
198
|
variables: options?.variables,
|
|
147
199
|
securityPolicy: options?.security,
|
|
200
|
+
projectRoot: configDir,
|
|
201
|
+
xrefPatterns,
|
|
202
|
+
fileRoots: Object.keys(fileRoots).length > 0 ? fileRoots : undefined,
|
|
203
|
+
siteConfig: site,
|
|
148
204
|
dev: options?.dev ?? false,
|
|
149
205
|
});
|
|
150
206
|
})();
|
|
@@ -188,7 +244,9 @@ export function createRefraktLoader(options) {
|
|
|
188
244
|
* dependencies in the host environment.
|
|
189
245
|
*/
|
|
190
246
|
export function createVirtualRefraktLoader(options) {
|
|
191
|
-
const { site, tree, reader, variables, security, basePath, dev } = options;
|
|
247
|
+
const { site, tree, reader, variables, security, basePath, projectRoot, xrefs, fileRoots: userFileRootsOption, dev } = options;
|
|
248
|
+
const xrefPatterns = compileConfiguredXrefPatterns(xrefs);
|
|
249
|
+
const userFileRoots = userFileRootsOption ?? {};
|
|
192
250
|
let _initPromise = null;
|
|
193
251
|
let _transform = null;
|
|
194
252
|
let _loader = null;
|
|
@@ -199,6 +257,27 @@ export function createVirtualRefraktLoader(options) {
|
|
|
199
257
|
_initPromise = (async () => {
|
|
200
258
|
const ctx = await assembleSiteContext(site);
|
|
201
259
|
_transform = ctx.transform;
|
|
260
|
+
// Plugin `configure` lifecycle — same as in createRefraktLoader.
|
|
261
|
+
// Virtual hosts pass the pre-resolved SiteConfig directly; plugins
|
|
262
|
+
// see the per-site config object rather than a full RefraktConfig.
|
|
263
|
+
const dynamicFileRoots = {};
|
|
264
|
+
const registerFileRoot = (namespace, absolutePath) => {
|
|
265
|
+
dynamicFileRoots[namespace] = absolutePath;
|
|
266
|
+
};
|
|
267
|
+
for (const pkg of ctx.communityPackages ?? []) {
|
|
268
|
+
if (pkg.pipeline?.configure) {
|
|
269
|
+
await pkg.pipeline.configure({
|
|
270
|
+
config: site,
|
|
271
|
+
configDir: projectRoot ?? '',
|
|
272
|
+
registerFileRoot,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const pluginRoots = { ...ctx.pluginFileRoots, ...dynamicFileRoots };
|
|
277
|
+
const { roots: fileRoots, warnings: fileRootWarnings } = mergeFileRoots(userFileRoots, pluginRoots);
|
|
278
|
+
for (const warning of fileRootWarnings) {
|
|
279
|
+
process.stderr.write(`refrakt: ${warning}\n`);
|
|
280
|
+
}
|
|
202
281
|
_loader = createVirtualSiteLoader({
|
|
203
282
|
tree,
|
|
204
283
|
basePath: basePath ?? '/',
|
|
@@ -208,6 +287,10 @@ export function createVirtualRefraktLoader(options) {
|
|
|
208
287
|
variables,
|
|
209
288
|
securityPolicy: security,
|
|
210
289
|
reader,
|
|
290
|
+
projectRoot,
|
|
291
|
+
xrefPatterns,
|
|
292
|
+
fileRoots: Object.keys(fileRoots).length > 0 ? fileRoots : undefined,
|
|
293
|
+
siteConfig: site,
|
|
211
294
|
dev: dev ?? false,
|
|
212
295
|
});
|
|
213
296
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refract-loader.js","sourceRoot":"","sources":["../src/refract-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9F,OAAO,EACN,gBAAgB,EAChB,uBAAuB,GAEvB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"refract-loader.js","sourceRoot":"","sources":["../src/refract-loader.ts"],"names":[],"mappings":"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"}
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityRegistration, EntityRegistry } from '@refrakt-md/types';
|
|
1
|
+
import type { EntityRegistration, EntityRegistry, EntityEdge, ResolvedEdge } from '@refrakt-md/types';
|
|
2
2
|
/**
|
|
3
3
|
* Concrete implementation of the cross-page entity registry.
|
|
4
4
|
*
|
|
@@ -6,19 +6,53 @@ import type { EntityRegistration, EntityRegistry } from '@refrakt-md/types';
|
|
|
6
6
|
* - byTypeAndId: primary index for getAll() and getById()
|
|
7
7
|
* - byTypeAndUrl: secondary index for getByUrl()
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* Page-scoped entries (SPEC-060, WORK-256) are keyed internally by
|
|
10
|
+
* `${sourceUrl}::${id}` in the primary index, so two pages can register
|
|
11
|
+
* the same `(type, id)` without colliding. Site-scoped entries (the
|
|
12
|
+
* default) keep using the bare `id` as their key, preserving the
|
|
13
|
+
* pre-WORK-256 collision semantics (last-write-wins on `(type, id)`).
|
|
14
|
+
*
|
|
15
|
+
* On collision within the same scope, the last registration wins.
|
|
10
16
|
*/
|
|
11
17
|
export declare class EntityRegistryImpl implements EntityRegistry {
|
|
12
18
|
private byTypeAndId;
|
|
13
19
|
private byTypeAndUrl;
|
|
20
|
+
/** Relationship graph (SPEC-072): outgoing edges keyed by `fromId`. */
|
|
21
|
+
private edgesByFrom;
|
|
14
22
|
register(entry: EntityRegistration): void;
|
|
15
23
|
/** All entities of a given type, in registration order */
|
|
16
24
|
getAll(type: string): EntityRegistration[];
|
|
17
25
|
/** All entities of a given type registered from a specific page URL */
|
|
18
26
|
getByUrl(type: string, url: string): EntityRegistration[];
|
|
19
|
-
/** Find a specific entity by type and id
|
|
20
|
-
|
|
27
|
+
/** Find a specific entity by type and id. Lookup order:
|
|
28
|
+
* 1. **Page-scoped match from `pageUrl`** — when `pageUrl` is provided,
|
|
29
|
+
* check for a page-scoped entry registered from that page. Fragments
|
|
30
|
+
* and trailing slashes are normalised so callers may pass the URL in
|
|
31
|
+
* any shape an adapter produces.
|
|
32
|
+
* 2. **Site-scoped match** — the entry registered with the bare `id`.
|
|
33
|
+
* 3. **Cross-page fallback** — when neither of the above hits, scan
|
|
34
|
+
* for any page-scoped entry with the same id from any page. This
|
|
35
|
+
* is the SPEC-060 cross-page drawer-trigger path: a drawer
|
|
36
|
+
* registered on page A is still findable when a xref on page B
|
|
37
|
+
* references its id. Returns the first match in registration
|
|
38
|
+
* order; cross-page id collisions are extraordinary enough that
|
|
39
|
+
* callers wanting strict resolution can pass `pageUrl` and check
|
|
40
|
+
* `sourceUrl` on the returned entry. */
|
|
41
|
+
getById(type: string, id: string, pageUrl?: string): EntityRegistration | undefined;
|
|
21
42
|
/** All registered entity type names */
|
|
22
43
|
getTypes(): string[];
|
|
44
|
+
/** Contribute a directed relationship edge (SPEC-072). Exact
|
|
45
|
+
* `(fromId, toId, kind)` duplicates are dropped; richer precedence is the
|
|
46
|
+
* contributor's concern. */
|
|
47
|
+
relate(edge: EntityEdge): void;
|
|
48
|
+
/** Outgoing edges of `id`, each with its target entity resolved (SPEC-072).
|
|
49
|
+
* Edges to unknown entities are dropped. */
|
|
50
|
+
getRelated(id: string, opts?: {
|
|
51
|
+
kind?: string | string[];
|
|
52
|
+
type?: string | string[];
|
|
53
|
+
}): ResolvedEdge[];
|
|
54
|
+
/** Resolve an edge's target entity: by `toType` when given, else by
|
|
55
|
+
* scanning registered types for a site-scoped id match. */
|
|
56
|
+
private resolveTarget;
|
|
23
57
|
}
|
|
24
58
|
//# sourceMappingURL=registry.d.ts.map
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtG;;;;;;;;;;;;;;GAcG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACxD,OAAO,CAAC,WAAW,CAAsD;IACzE,OAAO,CAAC,YAAY,CAAwD;IAC5E,uEAAuE;IACvE,OAAO,CAAC,WAAW,CAAmC;IAEtD,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAyCzC,0DAA0D;IAC1D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAM1C,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAIzD;;;;;;;;;;;;;gDAa4C;IAC5C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAiBnF,uCAAuC;IACvC,QAAQ,IAAI,MAAM,EAAE;IAIpB;;iCAE6B;IAC7B,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAU9B;iDAC6C;IAC7C,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,GAAG,YAAY,EAAE;IAgBrG;gEAC4D;IAC5D,OAAO,CAAC,aAAa;CAQrB"}
|
package/dist/registry.js
CHANGED
|
@@ -5,39 +5,56 @@
|
|
|
5
5
|
* - byTypeAndId: primary index for getAll() and getById()
|
|
6
6
|
* - byTypeAndUrl: secondary index for getByUrl()
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Page-scoped entries (SPEC-060, WORK-256) are keyed internally by
|
|
9
|
+
* `${sourceUrl}::${id}` in the primary index, so two pages can register
|
|
10
|
+
* the same `(type, id)` without colliding. Site-scoped entries (the
|
|
11
|
+
* default) keep using the bare `id` as their key, preserving the
|
|
12
|
+
* pre-WORK-256 collision semantics (last-write-wins on `(type, id)`).
|
|
13
|
+
*
|
|
14
|
+
* On collision within the same scope, the last registration wins.
|
|
9
15
|
*/
|
|
10
16
|
export class EntityRegistryImpl {
|
|
11
17
|
byTypeAndId = new Map();
|
|
12
18
|
byTypeAndUrl = new Map();
|
|
19
|
+
/** Relationship graph (SPEC-072): outgoing edges keyed by `fromId`. */
|
|
20
|
+
edgesByFrom = new Map();
|
|
13
21
|
register(entry) {
|
|
22
|
+
// Normalize empty-string sourceUrl to undefined — distinguishing
|
|
23
|
+
// "explicitly empty" from "missing" isn't useful, and the resolver
|
|
24
|
+
// treats both the same downstream.
|
|
25
|
+
const normalized = entry.sourceUrl === '' ? { ...entry, sourceUrl: undefined } : entry;
|
|
26
|
+
const key = primaryKey(normalized);
|
|
14
27
|
// Primary index
|
|
15
|
-
let typeMap = this.byTypeAndId.get(
|
|
28
|
+
let typeMap = this.byTypeAndId.get(normalized.type);
|
|
16
29
|
if (!typeMap) {
|
|
17
30
|
typeMap = new Map();
|
|
18
|
-
this.byTypeAndId.set(
|
|
19
|
-
}
|
|
20
|
-
typeMap.set(entry.id, entry);
|
|
21
|
-
// Secondary index
|
|
22
|
-
let urlMap = this.byTypeAndUrl.get(entry.type);
|
|
23
|
-
if (!urlMap) {
|
|
24
|
-
urlMap = new Map();
|
|
25
|
-
this.byTypeAndUrl.set(entry.type, urlMap);
|
|
31
|
+
this.byTypeAndId.set(normalized.type, typeMap);
|
|
26
32
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
typeMap.set(key, normalized);
|
|
34
|
+
// Secondary index — only meaningful when the entity has a sourceUrl.
|
|
35
|
+
// Entries without one (plan content not published to any site, etc.)
|
|
36
|
+
// are still in the primary index for getById; they just don't
|
|
37
|
+
// participate in URL-based lookups.
|
|
38
|
+
if (normalized.sourceUrl !== undefined) {
|
|
39
|
+
let urlMap = this.byTypeAndUrl.get(normalized.type);
|
|
40
|
+
if (!urlMap) {
|
|
41
|
+
urlMap = new Map();
|
|
42
|
+
this.byTypeAndUrl.set(normalized.type, urlMap);
|
|
43
|
+
}
|
|
44
|
+
const urlList = urlMap.get(normalized.sourceUrl);
|
|
45
|
+
if (urlList) {
|
|
46
|
+
const idx = urlList.findIndex(e => sameIdentity(e, normalized));
|
|
47
|
+
if (idx >= 0) {
|
|
48
|
+
urlList[idx] = normalized;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
urlList.push(normalized);
|
|
52
|
+
}
|
|
33
53
|
}
|
|
34
54
|
else {
|
|
35
|
-
|
|
55
|
+
urlMap.set(normalized.sourceUrl, [normalized]);
|
|
36
56
|
}
|
|
37
57
|
}
|
|
38
|
-
else {
|
|
39
|
-
urlMap.set(entry.sourceUrl, [entry]);
|
|
40
|
-
}
|
|
41
58
|
}
|
|
42
59
|
/** All entities of a given type, in registration order */
|
|
43
60
|
getAll(type) {
|
|
@@ -50,13 +67,130 @@ export class EntityRegistryImpl {
|
|
|
50
67
|
getByUrl(type, url) {
|
|
51
68
|
return this.byTypeAndUrl.get(type)?.get(url) ?? [];
|
|
52
69
|
}
|
|
53
|
-
/** Find a specific entity by type and id
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
/** Find a specific entity by type and id. Lookup order:
|
|
71
|
+
* 1. **Page-scoped match from `pageUrl`** — when `pageUrl` is provided,
|
|
72
|
+
* check for a page-scoped entry registered from that page. Fragments
|
|
73
|
+
* and trailing slashes are normalised so callers may pass the URL in
|
|
74
|
+
* any shape an adapter produces.
|
|
75
|
+
* 2. **Site-scoped match** — the entry registered with the bare `id`.
|
|
76
|
+
* 3. **Cross-page fallback** — when neither of the above hits, scan
|
|
77
|
+
* for any page-scoped entry with the same id from any page. This
|
|
78
|
+
* is the SPEC-060 cross-page drawer-trigger path: a drawer
|
|
79
|
+
* registered on page A is still findable when a xref on page B
|
|
80
|
+
* references its id. Returns the first match in registration
|
|
81
|
+
* order; cross-page id collisions are extraordinary enough that
|
|
82
|
+
* callers wanting strict resolution can pass `pageUrl` and check
|
|
83
|
+
* `sourceUrl` on the returned entry. */
|
|
84
|
+
getById(type, id, pageUrl) {
|
|
85
|
+
const typeMap = this.byTypeAndId.get(type);
|
|
86
|
+
if (!typeMap)
|
|
87
|
+
return undefined;
|
|
88
|
+
if (pageUrl !== undefined) {
|
|
89
|
+
const normalized = normalizePageUrl(stripFragment(pageUrl));
|
|
90
|
+
const pageHit = typeMap.get(pageScopedKey(normalized, id));
|
|
91
|
+
if (pageHit)
|
|
92
|
+
return pageHit;
|
|
93
|
+
}
|
|
94
|
+
const siteHit = typeMap.get(id);
|
|
95
|
+
if (siteHit)
|
|
96
|
+
return siteHit;
|
|
97
|
+
// Cross-page fallback for page-scoped entries with this id.
|
|
98
|
+
for (const entry of typeMap.values()) {
|
|
99
|
+
if (entry.id === id && entry.scope === 'page')
|
|
100
|
+
return entry;
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
56
103
|
}
|
|
57
104
|
/** All registered entity type names */
|
|
58
105
|
getTypes() {
|
|
59
106
|
return [...this.byTypeAndId.keys()];
|
|
60
107
|
}
|
|
108
|
+
/** Contribute a directed relationship edge (SPEC-072). Exact
|
|
109
|
+
* `(fromId, toId, kind)` duplicates are dropped; richer precedence is the
|
|
110
|
+
* contributor's concern. */
|
|
111
|
+
relate(edge) {
|
|
112
|
+
let list = this.edgesByFrom.get(edge.fromId);
|
|
113
|
+
if (!list) {
|
|
114
|
+
list = [];
|
|
115
|
+
this.edgesByFrom.set(edge.fromId, list);
|
|
116
|
+
}
|
|
117
|
+
if (list.some((e) => e.toId === edge.toId && e.kind === edge.kind))
|
|
118
|
+
return;
|
|
119
|
+
list.push(edge);
|
|
120
|
+
}
|
|
121
|
+
/** Outgoing edges of `id`, each with its target entity resolved (SPEC-072).
|
|
122
|
+
* Edges to unknown entities are dropped. */
|
|
123
|
+
getRelated(id, opts) {
|
|
124
|
+
const edges = this.edgesByFrom.get(id);
|
|
125
|
+
if (!edges)
|
|
126
|
+
return [];
|
|
127
|
+
const kinds = opts?.kind === undefined ? undefined : new Set(toArray(opts.kind));
|
|
128
|
+
const types = opts?.type === undefined ? undefined : new Set(toArray(opts.type));
|
|
129
|
+
const out = [];
|
|
130
|
+
for (const edge of edges) {
|
|
131
|
+
if (kinds && !kinds.has(edge.kind))
|
|
132
|
+
continue;
|
|
133
|
+
const target = this.resolveTarget(edge);
|
|
134
|
+
if (!target)
|
|
135
|
+
continue;
|
|
136
|
+
if (types && !types.has(target.type))
|
|
137
|
+
continue;
|
|
138
|
+
out.push({ kind: edge.kind, fromId: edge.fromId, toId: edge.toId, target });
|
|
139
|
+
}
|
|
140
|
+
return out;
|
|
141
|
+
}
|
|
142
|
+
/** Resolve an edge's target entity: by `toType` when given, else by
|
|
143
|
+
* scanning registered types for a site-scoped id match. */
|
|
144
|
+
resolveTarget(edge) {
|
|
145
|
+
if (edge.toType)
|
|
146
|
+
return this.getById(edge.toType, edge.toId);
|
|
147
|
+
for (const type of this.byTypeAndId.keys()) {
|
|
148
|
+
const hit = this.getById(type, edge.toId);
|
|
149
|
+
if (hit)
|
|
150
|
+
return hit;
|
|
151
|
+
}
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function toArray(v) {
|
|
156
|
+
return Array.isArray(v) ? v : [v];
|
|
157
|
+
}
|
|
158
|
+
/** Internal storage key for an entry. Site-scoped uses the bare id (so
|
|
159
|
+
* pre-WORK-256 callers keep working unchanged); page-scoped namespaces
|
|
160
|
+
* by the normalised page part of sourceUrl (fragment stripped, trailing
|
|
161
|
+
* slash trimmed) so the same id on the same page lands in one bucket
|
|
162
|
+
* regardless of href shape. A page-scoped entry without a usable
|
|
163
|
+
* sourceUrl falls back to the site-scoped key — that path is degenerate
|
|
164
|
+
* (it'll collide with site-scoped entries of the same id) and reflects
|
|
165
|
+
* a misconfiguration at the registration site rather than something the
|
|
166
|
+
* registry can recover from. */
|
|
167
|
+
function primaryKey(entry) {
|
|
168
|
+
if (entry.scope === 'page' && entry.sourceUrl) {
|
|
169
|
+
return pageScopedKey(normalizePageUrl(stripFragment(entry.sourceUrl)), entry.id);
|
|
170
|
+
}
|
|
171
|
+
return entry.id;
|
|
172
|
+
}
|
|
173
|
+
function pageScopedKey(pageUrl, id) {
|
|
174
|
+
return `${pageUrl}::${id}`;
|
|
175
|
+
}
|
|
176
|
+
function stripFragment(url) {
|
|
177
|
+
const i = url.indexOf('#');
|
|
178
|
+
return i === -1 ? url : url.slice(0, i);
|
|
179
|
+
}
|
|
180
|
+
/** Normalise a page URL for keying purposes — strip a trailing slash so
|
|
181
|
+
* adapters that emit `/x/` and ones that emit `/x` (or the resolver
|
|
182
|
+
* passing either form) coalesce into one bucket. Root (`/`) is preserved. */
|
|
183
|
+
function normalizePageUrl(url) {
|
|
184
|
+
if (url.length > 1 && url.endsWith('/'))
|
|
185
|
+
return url.slice(0, -1);
|
|
186
|
+
return url;
|
|
187
|
+
}
|
|
188
|
+
/** Two registrations refer to the same logical entry when their identity
|
|
189
|
+
* fields line up — used by the byTypeAndUrl secondary index to dedupe
|
|
190
|
+
* re-registrations from the same page. Scope participates because the
|
|
191
|
+
* same `(type, id)` can legitimately exist twice on a page when one is
|
|
192
|
+
* site-scoped and the other page-scoped (rare, but well-defined). */
|
|
193
|
+
function sameIdentity(a, b) {
|
|
194
|
+
return a.id === b.id && (a.scope ?? 'site') === (b.scope ?? 'site');
|
|
61
195
|
}
|
|
62
196
|
//# sourceMappingURL=registry.js.map
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/site.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { RenderableTreeNodes, Schema } from '@markdoc/markdoc';
|
|
2
|
+
import type { CompiledXrefPattern } from '@refrakt-md/runes';
|
|
2
3
|
import type { PageSeo, HeadingInfo } from '@refrakt-md/runes';
|
|
3
4
|
import type { Plugin, PipelineWarning, AggregatedData, SecurityPolicy } from '@refrakt-md/types';
|
|
4
5
|
import type { PipelineStats } from './pipeline.js';
|
|
@@ -8,6 +9,7 @@ import { Route } from './router.js';
|
|
|
8
9
|
import { ResolvedLayout } from './layout.js';
|
|
9
10
|
import { type ResolvedTintCascade } from './tint-cascade.js';
|
|
10
11
|
import { NavTree } from './navigation.js';
|
|
12
|
+
import { type FileRoots } from './file-roots.js';
|
|
11
13
|
/** Async reader for ad-hoc lookups in virtual (non-FS) hosting environments.
|
|
12
14
|
* Returns the file content or `null` when the path is unknown. */
|
|
13
15
|
export type VirtualReader = (path: string) => Promise<string | null>;
|
|
@@ -39,6 +41,12 @@ export interface SitePage {
|
|
|
39
41
|
* (SPEC-052). Adapters emit this as `data-theme` / `data-tint` /
|
|
40
42
|
* `data-tint-lock` attributes on `<html>` at SSR time. */
|
|
41
43
|
tintCascade: ResolvedTintCascade;
|
|
44
|
+
/** Provenance — file-backed by default, or contributed by a plugin (SPEC-069). */
|
|
45
|
+
source?: {
|
|
46
|
+
type: 'file' | 'contributed';
|
|
47
|
+
plugin?: string;
|
|
48
|
+
ruleIndex?: number;
|
|
49
|
+
};
|
|
42
50
|
}
|
|
43
51
|
/**
|
|
44
52
|
* Load a content directory and resolve all pages, routes, layouts, and navigation.
|
|
@@ -54,7 +62,7 @@ export interface SitePage {
|
|
|
54
62
|
* to `'trusted'` (current behaviour). Set `'strict'` for hosted-product use
|
|
55
63
|
* to strip scripts and harden the sandbox iframe.
|
|
56
64
|
*/
|
|
57
|
-
export declare function loadContent(dirPath: string, basePath?: string, icons?: Record<string, Record<string, string>>, additionalTags?: Record<string, Schema>, packages?: Plugin[], sandboxExamplesDir?: string, variables?: Record<string, unknown>, securityPolicy?: SecurityPolicy): Promise<Site>;
|
|
65
|
+
export declare function loadContent(dirPath: string, basePath?: string, icons?: Record<string, Record<string, string>>, additionalTags?: Record<string, Schema>, packages?: Plugin[], sandboxExamplesDir?: string, variables?: Record<string, unknown>, securityPolicy?: SecurityPolicy, projectRoot?: string, xrefPatterns?: CompiledXrefPattern[], fileRoots?: FileRoots, siteConfig?: unknown): Promise<Site>;
|
|
58
66
|
/** Options accepted by {@link loadContentFromTree}. */
|
|
59
67
|
export interface LoadContentFromTreeOptions {
|
|
60
68
|
/** URL base path for the Router. Default: `'/'`. */
|
|
@@ -81,6 +89,22 @@ export interface LoadContentFromTreeOptions {
|
|
|
81
89
|
* hosts can wire it once and not need to thread it again when new internal
|
|
82
90
|
* consumers land. */
|
|
83
91
|
reader?: VirtualReader;
|
|
92
|
+
/** Absolute path to the project root (where `refrakt.config.json` lives).
|
|
93
|
+
* Used to compute `$file.path` as a project-root-relative POSIX path.
|
|
94
|
+
* When omitted, `$file.path` falls back to the page's content-root-relative
|
|
95
|
+
* path. Hosted environments that have a meaningful project-root concept
|
|
96
|
+
* should pass it; pure in-memory hosts that don't can leave it undefined. */
|
|
97
|
+
projectRoot?: string;
|
|
98
|
+
/** Compiled xref patterns from `refrakt.config.json#/xrefs`. Hosted
|
|
99
|
+
* environments that own their config resolution can compile patterns via
|
|
100
|
+
* `compileXrefPatterns` and pass them here. */
|
|
101
|
+
xrefPatterns?: CompiledXrefPattern[];
|
|
102
|
+
/** Registered file roots — namespace → absolute directory path. */
|
|
103
|
+
fileRoots?: FileRoots;
|
|
104
|
+
/** Per-site config slice — passed to contributePages hooks so the built-in
|
|
105
|
+
* entityRoutes adapter can read `entityRoutes` and other site-scoped
|
|
106
|
+
* config. */
|
|
107
|
+
siteConfig?: unknown;
|
|
84
108
|
}
|
|
85
109
|
/**
|
|
86
110
|
* Like {@link loadContent}, but driven by a pre-built {@link ContentTree}
|
package/dist/site.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAQ,mBAAmB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1E,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"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"}
|