@lensmap/astro-loader 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter.d.ts +2 -2
- package/dist/index.js +102 -8
- package/package.json +13 -14
package/dist/adapter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type SemanticGraph } from "@lensmap/document";
|
|
1
|
+
import { type SemanticGraph, type VocabularyInput } from "@lensmap/document";
|
|
2
2
|
export interface ExecutionOptions {
|
|
3
3
|
/** Exact local files, compared after realpath. Admission is not sandboxing. */
|
|
4
4
|
mdx?: {
|
|
@@ -20,6 +20,6 @@ export interface ParsedMap {
|
|
|
20
20
|
authoredFrontmatter: Record<string, unknown>;
|
|
21
21
|
graph: SemanticGraph;
|
|
22
22
|
}
|
|
23
|
-
export declare function parseMap(source: string, uri: string): ParsedMap;
|
|
23
|
+
export declare function parseMap(source: string, uri: string, vocabulary?: VocabularyInput): ParsedMap;
|
|
24
24
|
export declare function moduleStem(path: string): string;
|
|
25
25
|
export declare function writeGenerated(path: string, content: string): boolean;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { mkdirSync, readFileSync as readFileSync2 } from "node:fs";
|
|
2
|
+
import { mkdirSync, readFileSync as readFileSync2, realpathSync as realpathSync2 } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5
|
+
import { readProjectVocabulary } from "@lensmap/document/project";
|
|
5
6
|
import { glob } from "astro/loaders";
|
|
6
7
|
|
|
7
8
|
// src/adapter.ts
|
|
@@ -27,8 +28,13 @@ function canExecute(source, options, installed) {
|
|
|
27
28
|
return false;
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
|
-
function parseMap(source, uri) {
|
|
31
|
-
const snapshot = new DocumentSession(
|
|
31
|
+
function parseMap(source, uri, vocabulary) {
|
|
32
|
+
const snapshot = new DocumentSession(
|
|
33
|
+
uri,
|
|
34
|
+
source,
|
|
35
|
+
void 0,
|
|
36
|
+
vocabulary
|
|
37
|
+
).snapshot();
|
|
32
38
|
if (!snapshot.valid || !snapshot.graph)
|
|
33
39
|
throw new Error(
|
|
34
40
|
`Invalid Lensmap ${uri}: ${JSON.stringify(snapshot.diagnostics)}`
|
|
@@ -98,10 +104,76 @@ function lensmap(options = {}) {
|
|
|
98
104
|
let config;
|
|
99
105
|
let renderer;
|
|
100
106
|
let installedMdx = false;
|
|
107
|
+
let vocabulary = {};
|
|
108
|
+
let vocabularyFiles = [];
|
|
109
|
+
let generation = 0;
|
|
110
|
+
const maps = /* @__PURE__ */ new Map();
|
|
111
|
+
async function reloadVocabulary() {
|
|
112
|
+
const current = ++generation;
|
|
113
|
+
const root = realpathSync2(fileURLToPath2(config.root));
|
|
114
|
+
const loaded = await readProjectVocabulary(root);
|
|
115
|
+
if (current !== generation) return false;
|
|
116
|
+
vocabulary = loaded.input;
|
|
117
|
+
vocabularyFiles = loaded.files;
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
async function publishVocabulary(server) {
|
|
121
|
+
if (!await reloadVocabulary()) return [];
|
|
122
|
+
server.watcher.add(vocabularyFiles);
|
|
123
|
+
for (const [uri, map] of maps) {
|
|
124
|
+
try {
|
|
125
|
+
const { graph } = parseMap(map.source, uri, vocabulary);
|
|
126
|
+
server.ws.send("lensmap:vocabulary", {
|
|
127
|
+
id: map.id,
|
|
128
|
+
stale: false,
|
|
129
|
+
edges: graph.edges.map(
|
|
130
|
+
({ key, from, to, kind, type, presentation }) => ({
|
|
131
|
+
key,
|
|
132
|
+
from,
|
|
133
|
+
to,
|
|
134
|
+
kind,
|
|
135
|
+
type,
|
|
136
|
+
presentation
|
|
137
|
+
})
|
|
138
|
+
),
|
|
139
|
+
nodes: graph.nodes.map(({ key, destination }) => ({
|
|
140
|
+
key,
|
|
141
|
+
destination
|
|
142
|
+
}))
|
|
143
|
+
});
|
|
144
|
+
} catch (error) {
|
|
145
|
+
server.config.logger.error(
|
|
146
|
+
error instanceof Error ? error.message : String(error)
|
|
147
|
+
);
|
|
148
|
+
server.ws.send("lensmap:vocabulary", { id: map.id, stale: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
for (const uri of maps.keys()) {
|
|
152
|
+
for (const environment of Object.values(server.environments)) {
|
|
153
|
+
for (const module of environment.moduleGraph.getModulesByFile(
|
|
154
|
+
fileURLToPath2(uri)
|
|
155
|
+
) ?? []) {
|
|
156
|
+
environment.moduleGraph.invalidateModule(module);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
101
161
|
const mdxModules = /* @__PURE__ */ new Map();
|
|
102
162
|
return {
|
|
103
163
|
name: "@lensmap/astro-loader",
|
|
104
164
|
hooks: {
|
|
165
|
+
"astro:server:setup": ({ server }) => {
|
|
166
|
+
server.watcher.add(vocabularyFiles);
|
|
167
|
+
const changed = (path) => {
|
|
168
|
+
if (vocabularyFiles.includes(path)) void publishVocabulary(server);
|
|
169
|
+
};
|
|
170
|
+
server.watcher.on("add", changed);
|
|
171
|
+
server.watcher.on("unlink", changed);
|
|
172
|
+
server.httpServer?.once("close", () => {
|
|
173
|
+
server.watcher.off("add", changed);
|
|
174
|
+
server.watcher.off("unlink", changed);
|
|
175
|
+
});
|
|
176
|
+
},
|
|
105
177
|
"astro:config:setup": (setup) => {
|
|
106
178
|
const version = JSON.parse(
|
|
107
179
|
readFileSync2(
|
|
@@ -124,9 +196,22 @@ function lensmap(options = {}) {
|
|
|
124
196
|
{
|
|
125
197
|
name: "lensmap-source-relative-mdx",
|
|
126
198
|
enforce: "pre",
|
|
127
|
-
resolveId(id) {
|
|
199
|
+
resolveId(id, _importer, resolveOptions) {
|
|
200
|
+
if (resolveOptions.ssr && id === "@lensmap/document")
|
|
201
|
+
return {
|
|
202
|
+
id: fileURLToPath2(
|
|
203
|
+
new URL(import.meta.resolve("@lensmap/document"))
|
|
204
|
+
),
|
|
205
|
+
external: true
|
|
206
|
+
};
|
|
128
207
|
if (mdxModules.has(id)) return id;
|
|
129
208
|
},
|
|
209
|
+
async hotUpdate(context) {
|
|
210
|
+
if (!vocabularyFiles.includes(context.file)) return;
|
|
211
|
+
if (this.environment.name !== "client") return [];
|
|
212
|
+
await publishVocabulary(context.server);
|
|
213
|
+
return [];
|
|
214
|
+
},
|
|
130
215
|
load(id) {
|
|
131
216
|
const module = mdxModules.get(id.split("?")[0] ?? id);
|
|
132
217
|
if (!module) return;
|
|
@@ -144,7 +229,8 @@ function lensmap(options = {}) {
|
|
|
144
229
|
getEntryInfo({ contents, fileUrl }) {
|
|
145
230
|
const { authoredFrontmatter: data, graph } = parseMap(
|
|
146
231
|
contents,
|
|
147
|
-
fileUrl.href
|
|
232
|
+
fileUrl.href,
|
|
233
|
+
vocabulary
|
|
148
234
|
);
|
|
149
235
|
return {
|
|
150
236
|
data,
|
|
@@ -155,9 +241,12 @@ function lensmap(options = {}) {
|
|
|
155
241
|
},
|
|
156
242
|
async getRenderModule({ contents, fileUrl }) {
|
|
157
243
|
const path = fileURLToPath2(fileUrl);
|
|
244
|
+
const mapId = moduleStem(path);
|
|
245
|
+
maps.set(fileUrl.href, { source: contents, id: mapId });
|
|
158
246
|
const { graph, authoredFrontmatter } = parseMap(
|
|
159
247
|
contents,
|
|
160
|
-
fileUrl.href
|
|
248
|
+
fileUrl.href,
|
|
249
|
+
vocabulary
|
|
161
250
|
);
|
|
162
251
|
const executable = canExecute(
|
|
163
252
|
{ kind: "local", path },
|
|
@@ -216,7 +305,7 @@ ${imports.join("\n")}
|
|
|
216
305
|
const graph = ${quote(graph)};
|
|
217
306
|
const authoredFrontmatter = ${quote(authoredFrontmatter)};
|
|
218
307
|
---
|
|
219
|
-
<MapContent {...Astro.props} graph={graph} authoredFrontmatter={authoredFrontmatter} executable={${executable}}>
|
|
308
|
+
<MapContent {...Astro.props} graph={graph} mapId={${quote(mapId)}} authoredFrontmatter={authoredFrontmatter} executable={${executable}}>
|
|
220
309
|
${slots.join("\n")}
|
|
221
310
|
</MapContent>
|
|
222
311
|
`
|
|
@@ -228,8 +317,13 @@ ${slots.join("\n")}
|
|
|
228
317
|
}
|
|
229
318
|
});
|
|
230
319
|
},
|
|
231
|
-
"astro:config:done": ({ config: resolved }) => {
|
|
320
|
+
"astro:config:done": async ({ config: resolved }) => {
|
|
232
321
|
config = resolved;
|
|
322
|
+
await reloadVocabulary();
|
|
323
|
+
if (vocabulary.error)
|
|
324
|
+
throw new Error(
|
|
325
|
+
`Invalid Lensmap project vocabulary: ${vocabulary.error}`
|
|
326
|
+
);
|
|
233
327
|
installedMdx = resolved.integrations.some(
|
|
234
328
|
(integration) => integration.name === "@astrojs/mdx"
|
|
235
329
|
);
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.3.0",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
@@ -27,14 +27,8 @@
|
|
|
27
27
|
},
|
|
28
28
|
"./components/*": "./dist/components/*"
|
|
29
29
|
},
|
|
30
|
-
"scripts": {
|
|
31
|
-
"build": "node build.mjs",
|
|
32
|
-
"typecheck": "tsc --noEmit",
|
|
33
|
-
"test": "node --test test/*.test.ts",
|
|
34
|
-
"prepack": "pnpm build"
|
|
35
|
-
},
|
|
36
30
|
"dependencies": {
|
|
37
|
-
"@lensmap/document": "
|
|
31
|
+
"@lensmap/document": "0.3.0",
|
|
38
32
|
"rehype-parse": "9.0.1",
|
|
39
33
|
"rehype-sanitize": "6.0.0",
|
|
40
34
|
"rehype-stringify": "10.0.1",
|
|
@@ -42,19 +36,24 @@
|
|
|
42
36
|
"yaml": "2.9.1"
|
|
43
37
|
},
|
|
44
38
|
"peerDependencies": {
|
|
45
|
-
"
|
|
46
|
-
"
|
|
39
|
+
"@astrojs/mdx": "8.1.0",
|
|
40
|
+
"astro": "7.4.0"
|
|
47
41
|
},
|
|
48
42
|
"devDependencies": {
|
|
49
|
-
"astro": "7.4.0",
|
|
50
43
|
"@astrojs/mdx": "8.1.0",
|
|
44
|
+
"@types/node": "24.19.2",
|
|
45
|
+
"astro": "7.4.0",
|
|
51
46
|
"esbuild": "0.28.2",
|
|
52
|
-
"typescript": "7.0.2"
|
|
53
|
-
"@types/node": "24.19.2"
|
|
47
|
+
"typescript": "7.0.2"
|
|
54
48
|
},
|
|
55
49
|
"peerDependenciesMeta": {
|
|
56
50
|
"@astrojs/mdx": {
|
|
57
51
|
"optional": true
|
|
58
52
|
}
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "node build.mjs",
|
|
56
|
+
"typecheck": "tsc --noEmit",
|
|
57
|
+
"test": "node --test test/*.test.ts"
|
|
59
58
|
}
|
|
60
|
-
}
|
|
59
|
+
}
|