@flowview/astro 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +362 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andersseen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FlowviewViteOptions } from '@flowview/vite';
|
|
2
|
+
import { AstroIntegration } from 'astro';
|
|
3
|
+
|
|
4
|
+
interface FlowviewAstroOptions extends FlowviewViteOptions {
|
|
5
|
+
}
|
|
6
|
+
declare function flowview(options?: FlowviewAstroOptions): AstroIntegration;
|
|
7
|
+
|
|
8
|
+
export { type FlowviewAstroOptions, flowview as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { parse } from "@astrojs/compiler/sync";
|
|
3
|
+
import { createHash } from "crypto";
|
|
4
|
+
import flowviewVite, {
|
|
5
|
+
compileFlowview,
|
|
6
|
+
resolveCompilerPath
|
|
7
|
+
} from "@flowview/vite";
|
|
8
|
+
import MagicString from "magic-string";
|
|
9
|
+
var FlowviewAstroError = class extends Error {
|
|
10
|
+
constructor(message, filename, offset, code) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.filename = filename;
|
|
13
|
+
this.name = "FlowviewAstroError";
|
|
14
|
+
const { line, column } = lineAndColumn(code, offset);
|
|
15
|
+
this.loc = { line, column };
|
|
16
|
+
}
|
|
17
|
+
filename;
|
|
18
|
+
loc;
|
|
19
|
+
};
|
|
20
|
+
var VIRTUAL_PREFIX = "virtual:flowview-astro/";
|
|
21
|
+
var RESOLVED_VIRTUAL_PREFIX = "\0" + VIRTUAL_PREFIX;
|
|
22
|
+
function flowview(options = {}) {
|
|
23
|
+
return {
|
|
24
|
+
name: "@flowview/astro",
|
|
25
|
+
hooks: {
|
|
26
|
+
"astro:config:setup": ({ updateConfig }) => {
|
|
27
|
+
updateConfig({
|
|
28
|
+
vite: {
|
|
29
|
+
plugins: [flowviewVite(options), flowviewAstroPlugin(options)]
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function flowviewAstroPlugin(options) {
|
|
37
|
+
const runtimeImport = options.runtimeImport ?? "@flowview/runtime";
|
|
38
|
+
const compilerPath = resolveCompilerPath(options.compilerPath);
|
|
39
|
+
const virtualModules = /* @__PURE__ */ new Map();
|
|
40
|
+
const virtualIdsByFile = /* @__PURE__ */ new Map();
|
|
41
|
+
return {
|
|
42
|
+
name: "@flowview/astro:embedded",
|
|
43
|
+
enforce: "pre",
|
|
44
|
+
configResolved(config) {
|
|
45
|
+
const plugins = config.plugins;
|
|
46
|
+
const ownIndex = plugins.findIndex(
|
|
47
|
+
(plugin) => plugin.name === "@flowview/astro:embedded"
|
|
48
|
+
);
|
|
49
|
+
const astroIndex = plugins.findIndex(
|
|
50
|
+
(plugin) => plugin.name === "astro:build"
|
|
51
|
+
);
|
|
52
|
+
if (ownIndex > astroIndex && astroIndex !== -1) {
|
|
53
|
+
const [plugin] = plugins.splice(ownIndex, 1);
|
|
54
|
+
if (plugin) plugins.splice(astroIndex, 0, plugin);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
resolveId(id) {
|
|
58
|
+
if (id.startsWith(VIRTUAL_PREFIX)) {
|
|
59
|
+
return RESOLVED_VIRTUAL_PREFIX + id.slice(VIRTUAL_PREFIX.length);
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
},
|
|
63
|
+
async load(id) {
|
|
64
|
+
if (!id.startsWith(RESOLVED_VIRTUAL_PREFIX)) return null;
|
|
65
|
+
const publicId = VIRTUAL_PREFIX + id.slice(RESOLVED_VIRTUAL_PREFIX.length);
|
|
66
|
+
const template = virtualModules.get(publicId);
|
|
67
|
+
if (template === void 0) {
|
|
68
|
+
throw new Error(`Missing flowview virtual module: ${publicId}`);
|
|
69
|
+
}
|
|
70
|
+
const { code } = await compileFlowview(template.source, {
|
|
71
|
+
filename: template.filename,
|
|
72
|
+
lineOffset: template.lineOffset,
|
|
73
|
+
runtimeImport,
|
|
74
|
+
compilerPath
|
|
75
|
+
});
|
|
76
|
+
return code;
|
|
77
|
+
},
|
|
78
|
+
transform(code, id) {
|
|
79
|
+
const cleanId = stripQuery(id);
|
|
80
|
+
if (!cleanId.endsWith(".astro") || !code.includes("flowview")) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
return transformAstroSource(
|
|
85
|
+
code,
|
|
86
|
+
cleanId,
|
|
87
|
+
virtualModules,
|
|
88
|
+
virtualIdsByFile
|
|
89
|
+
);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (error instanceof FlowviewAstroError) {
|
|
92
|
+
const locatedError = {
|
|
93
|
+
message: error.message,
|
|
94
|
+
id: cleanId,
|
|
95
|
+
loc: error.loc
|
|
96
|
+
};
|
|
97
|
+
if (typeof this.error === "function") {
|
|
98
|
+
this.error(locatedError);
|
|
99
|
+
}
|
|
100
|
+
throw locatedError;
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function transformAstroSource(code, filename, virtualModules, virtualIdsByFile) {
|
|
108
|
+
const templates = findEmbeddedTemplates(code, filename);
|
|
109
|
+
if (templates.length === 0) return null;
|
|
110
|
+
const fileHash = createHash("sha256").update(filename).digest("hex").slice(0, 12);
|
|
111
|
+
const imports = [];
|
|
112
|
+
const previousIds = virtualIdsByFile.get(filename);
|
|
113
|
+
previousIds?.forEach((id) => virtualModules.delete(id));
|
|
114
|
+
const currentIds = /* @__PURE__ */ new Set();
|
|
115
|
+
const transformed = new MagicString(code);
|
|
116
|
+
templates.forEach((template, index) => {
|
|
117
|
+
const renderName = `__flowviewRender${index}`;
|
|
118
|
+
const contentHash = createHash("sha256").update(template.source).digest("hex").slice(0, 12);
|
|
119
|
+
const virtualId = `${VIRTUAL_PREFIX}${fileHash}/${index}-${contentHash}.js`;
|
|
120
|
+
virtualModules.set(virtualId, {
|
|
121
|
+
source: template.source,
|
|
122
|
+
filename,
|
|
123
|
+
lineOffset: template.lineOffset
|
|
124
|
+
});
|
|
125
|
+
currentIds.add(virtualId);
|
|
126
|
+
imports.push(`import { render as ${renderName} } from "${virtualId}";`);
|
|
127
|
+
transformed.overwrite(
|
|
128
|
+
template.start,
|
|
129
|
+
template.end,
|
|
130
|
+
`<Fragment set:html={${renderName}(${template.contextExpression})} />`
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
virtualIdsByFile.set(filename, currentIds);
|
|
134
|
+
injectFrontmatter(transformed, code, imports.join("\n"));
|
|
135
|
+
return {
|
|
136
|
+
code: transformed.toString(),
|
|
137
|
+
map: transformed.generateMap({
|
|
138
|
+
source: filename,
|
|
139
|
+
includeContent: true,
|
|
140
|
+
hires: true
|
|
141
|
+
})
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function findEmbeddedTemplates(code, filename) {
|
|
145
|
+
const { ast } = parse(code, { position: true });
|
|
146
|
+
const templates = [];
|
|
147
|
+
visitAstroNodes(ast, (node) => {
|
|
148
|
+
if (!isTagNode(node) || node.name !== "template") return true;
|
|
149
|
+
const flowviewAttribute = node.attributes.find(
|
|
150
|
+
(attribute) => attribute.name === "flowview"
|
|
151
|
+
);
|
|
152
|
+
if (!flowviewAttribute) return true;
|
|
153
|
+
const firstKnownOffset = flowviewAttribute.position?.start.offset ?? node.position?.start.offset ?? 0;
|
|
154
|
+
const openStart = code.lastIndexOf("<", firstKnownOffset);
|
|
155
|
+
const openEnd = findTagEnd(code, openStart);
|
|
156
|
+
if (openStart === -1 || openEnd === -1) {
|
|
157
|
+
throw new FlowviewAstroError(
|
|
158
|
+
"flowview embedded template has an invalid opening tag.",
|
|
159
|
+
filename,
|
|
160
|
+
firstKnownOffset,
|
|
161
|
+
code
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
const contextAttribute = node.attributes.find(
|
|
165
|
+
(attribute) => attribute.name === "context"
|
|
166
|
+
);
|
|
167
|
+
const flowviewExpression = flowviewAttribute.kind === "expression" ? flowviewAttribute.value.trim() : "";
|
|
168
|
+
const contextExpression = flowviewExpression !== "" ? flowviewExpression : contextAttribute?.kind === "expression" ? contextAttribute.value.trim() : "";
|
|
169
|
+
if (!contextExpression) {
|
|
170
|
+
throw new FlowviewAstroError(
|
|
171
|
+
"flowview embedded templates require a context expression: flowview={...} or context={...}.",
|
|
172
|
+
filename,
|
|
173
|
+
openStart,
|
|
174
|
+
code
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
if (flowviewExpression !== "" && contextAttribute?.kind === "expression") {
|
|
178
|
+
throw new FlowviewAstroError(
|
|
179
|
+
"flowview embedded templates must not combine flowview={...} with context={...}; use one of them.",
|
|
180
|
+
filename,
|
|
181
|
+
openStart,
|
|
182
|
+
code
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
const closeStart = findMatchingTemplateClose(code, openEnd + 1);
|
|
186
|
+
if (closeStart === -1) {
|
|
187
|
+
throw new FlowviewAstroError(
|
|
188
|
+
"flowview embedded template is missing </template>.",
|
|
189
|
+
filename,
|
|
190
|
+
openStart,
|
|
191
|
+
code
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
const closeTagEnd = findTagEnd(code, closeStart);
|
|
195
|
+
if (closeTagEnd === -1) {
|
|
196
|
+
throw new FlowviewAstroError(
|
|
197
|
+
"flowview embedded template has an invalid closing tag.",
|
|
198
|
+
filename,
|
|
199
|
+
closeStart,
|
|
200
|
+
code
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
templates.push({
|
|
204
|
+
source: code.slice(openEnd + 1, closeStart),
|
|
205
|
+
contextExpression,
|
|
206
|
+
start: openStart,
|
|
207
|
+
end: closeTagEnd + 1,
|
|
208
|
+
lineOffset: countNewlines(code, 0, openEnd + 1)
|
|
209
|
+
});
|
|
210
|
+
return false;
|
|
211
|
+
});
|
|
212
|
+
return templates.sort((left, right) => left.start - right.start);
|
|
213
|
+
}
|
|
214
|
+
function visitAstroNodes(root, visitor) {
|
|
215
|
+
for (const child of root.children) {
|
|
216
|
+
const shouldVisitChildren = visitor(child);
|
|
217
|
+
if (shouldVisitChildren && "children" in child) {
|
|
218
|
+
visitAstroNodes(child, visitor);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function isTagNode(node) {
|
|
223
|
+
return ["element", "component", "custom-element", "fragment"].includes(
|
|
224
|
+
node.type
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
function findMatchingTemplateClose(code, start) {
|
|
228
|
+
let cursor = start;
|
|
229
|
+
let depth = 1;
|
|
230
|
+
while (cursor < code.length) {
|
|
231
|
+
const tagStart = code.indexOf("<", cursor);
|
|
232
|
+
if (tagStart === -1) return -1;
|
|
233
|
+
if (startsWithIgnoreCase(code, "<!--", tagStart)) {
|
|
234
|
+
const commentEnd = code.indexOf("-->", tagStart + 4);
|
|
235
|
+
if (commentEnd === -1) return -1;
|
|
236
|
+
cursor = commentEnd + 3;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const rawTextTag = ["script", "style"].find(
|
|
240
|
+
(name) => startsWithIgnoreCase(code, `<${name}`, tagStart) && isTagNameBoundary(code[tagStart + name.length + 1])
|
|
241
|
+
);
|
|
242
|
+
if (rawTextTag !== void 0) {
|
|
243
|
+
const closeStart = findCaseInsensitive(
|
|
244
|
+
code,
|
|
245
|
+
`</${rawTextTag}>`,
|
|
246
|
+
tagStart + 1
|
|
247
|
+
);
|
|
248
|
+
if (closeStart === -1) return -1;
|
|
249
|
+
cursor = closeStart + rawTextTag.length + 3;
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (startsWithIgnoreCase(code, "<template", tagStart) && isTagNameBoundary(code[tagStart + "<template".length])) {
|
|
253
|
+
const tagEnd = findTagEnd(code, tagStart);
|
|
254
|
+
if (tagEnd === -1) return -1;
|
|
255
|
+
depth += 1;
|
|
256
|
+
cursor = tagEnd + 1;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (startsWithIgnoreCase(code, "</template", tagStart) && isTagNameBoundary(code[tagStart + "</template".length])) {
|
|
260
|
+
const tagEnd = findTagEnd(code, tagStart);
|
|
261
|
+
if (tagEnd === -1) return -1;
|
|
262
|
+
depth -= 1;
|
|
263
|
+
if (depth === 0) return tagStart;
|
|
264
|
+
cursor = tagEnd + 1;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
cursor = tagStart + 1;
|
|
268
|
+
}
|
|
269
|
+
return -1;
|
|
270
|
+
}
|
|
271
|
+
function findTagEnd(code, start) {
|
|
272
|
+
let quote = null;
|
|
273
|
+
let braceDepth = 0;
|
|
274
|
+
for (let index = start; index < code.length; index += 1) {
|
|
275
|
+
const character = code[index];
|
|
276
|
+
if (quote !== null) {
|
|
277
|
+
if (character === "\\") index += 1;
|
|
278
|
+
else if (character === quote) quote = null;
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (character === '"' || character === "'" || character === "`") {
|
|
282
|
+
quote = character;
|
|
283
|
+
} else if (character === "{") {
|
|
284
|
+
braceDepth += 1;
|
|
285
|
+
} else if (character === "}") {
|
|
286
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
287
|
+
} else if (character === ">" && braceDepth === 0) {
|
|
288
|
+
return index;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return -1;
|
|
292
|
+
}
|
|
293
|
+
function injectFrontmatter(transformed, original, content) {
|
|
294
|
+
const closingFence = findFrontmatterClose(original);
|
|
295
|
+
if (closingFence !== -1) {
|
|
296
|
+
transformed.appendLeft(closingFence, `${content}
|
|
297
|
+
`);
|
|
298
|
+
} else {
|
|
299
|
+
transformed.prepend(`---
|
|
300
|
+
${content}
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function findFrontmatterClose(code) {
|
|
307
|
+
const firstLineEnd = code.indexOf("\n");
|
|
308
|
+
if (firstLineEnd === -1 || code.slice(0, firstLineEnd).trim() !== "---") {
|
|
309
|
+
return -1;
|
|
310
|
+
}
|
|
311
|
+
let lineStart = firstLineEnd + 1;
|
|
312
|
+
while (lineStart <= code.length) {
|
|
313
|
+
const lineEnd = code.indexOf("\n", lineStart);
|
|
314
|
+
const end = lineEnd === -1 ? code.length : lineEnd;
|
|
315
|
+
if (code.slice(lineStart, end).trim() === "---") return lineStart;
|
|
316
|
+
if (lineEnd === -1) break;
|
|
317
|
+
lineStart = lineEnd + 1;
|
|
318
|
+
}
|
|
319
|
+
return -1;
|
|
320
|
+
}
|
|
321
|
+
function isTagNameBoundary(character) {
|
|
322
|
+
return character === void 0 || /[\s/>]/.test(character);
|
|
323
|
+
}
|
|
324
|
+
function countNewlines(value, start, end) {
|
|
325
|
+
let count = 0;
|
|
326
|
+
for (let index = start; index < end; index += 1) {
|
|
327
|
+
if (value[index] === "\n") count += 1;
|
|
328
|
+
}
|
|
329
|
+
return count;
|
|
330
|
+
}
|
|
331
|
+
function lineAndColumn(source, offset) {
|
|
332
|
+
let line = 1;
|
|
333
|
+
let column = 1;
|
|
334
|
+
for (let index = 0; index < offset && index < source.length; index += 1) {
|
|
335
|
+
if (source[index] === "\n") {
|
|
336
|
+
line += 1;
|
|
337
|
+
column = 1;
|
|
338
|
+
} else {
|
|
339
|
+
column += 1;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return { line, column };
|
|
343
|
+
}
|
|
344
|
+
function startsWithIgnoreCase(value, prefix, start = 0) {
|
|
345
|
+
return value.slice(start, start + prefix.length).toLowerCase() === prefix.toLowerCase();
|
|
346
|
+
}
|
|
347
|
+
function findCaseInsensitive(value, search, start = 0) {
|
|
348
|
+
const lowerSearch = search.toLowerCase();
|
|
349
|
+
for (let index = start; index <= value.length - search.length; index += 1) {
|
|
350
|
+
if (value.slice(index, index + search.length).toLowerCase() === lowerSearch) {
|
|
351
|
+
return index;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return -1;
|
|
355
|
+
}
|
|
356
|
+
function stripQuery(id) {
|
|
357
|
+
return id.split("?", 1)[0] ?? id;
|
|
358
|
+
}
|
|
359
|
+
export {
|
|
360
|
+
flowview as default
|
|
361
|
+
};
|
|
362
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { parse } from \"@astrojs/compiler/sync\";\nimport type {\n Node as AstroNode,\n ParentLikeNode,\n TagLikeNode,\n} from \"@astrojs/compiler/types\";\nimport { createHash } from \"node:crypto\";\nimport flowviewVite, {\n compileFlowview,\n resolveCompilerPath,\n type FlowviewViteOptions,\n} from \"@flowview/vite\";\nimport type { AstroIntegration } from \"astro\";\nimport MagicString from \"magic-string\";\nimport type { Plugin } from \"vite\";\n\nexport interface FlowviewAstroOptions extends FlowviewViteOptions {}\n\ninterface EmbeddedTemplate {\n source: string;\n contextExpression: string;\n start: number;\n end: number;\n lineOffset: number;\n}\n\ninterface VirtualTemplate {\n source: string;\n filename: string;\n lineOffset: number;\n}\n\nclass FlowviewAstroError extends Error {\n readonly loc: { line: number; column: number };\n\n constructor(\n message: string,\n readonly filename: string,\n offset: number,\n code: string,\n ) {\n super(message);\n this.name = \"FlowviewAstroError\";\n const { line, column } = lineAndColumn(code, offset);\n this.loc = { line, column };\n }\n}\n\nconst VIRTUAL_PREFIX = \"virtual:flowview-astro/\";\nconst RESOLVED_VIRTUAL_PREFIX = \"\\0\" + VIRTUAL_PREFIX;\n\nexport default function flowview(\n options: FlowviewAstroOptions = {},\n): AstroIntegration {\n return {\n name: \"@flowview/astro\",\n hooks: {\n \"astro:config:setup\": ({ updateConfig }) => {\n updateConfig({\n vite: {\n plugins: [flowviewVite(options), flowviewAstroPlugin(options)],\n },\n });\n },\n },\n };\n}\n\nfunction flowviewAstroPlugin(options: FlowviewAstroOptions): Plugin {\n const runtimeImport = options.runtimeImport ?? \"@flowview/runtime\";\n const compilerPath = resolveCompilerPath(options.compilerPath);\n const virtualModules = new Map<string, VirtualTemplate>();\n const virtualIdsByFile = new Map<string, Set<string>>();\n\n return {\n name: \"@flowview/astro:embedded\",\n enforce: \"pre\",\n\n configResolved(config) {\n const plugins = config.plugins as Plugin[];\n const ownIndex = plugins.findIndex(\n (plugin) => plugin.name === \"@flowview/astro:embedded\",\n );\n const astroIndex = plugins.findIndex(\n (plugin) => plugin.name === \"astro:build\",\n );\n\n if (ownIndex > astroIndex && astroIndex !== -1) {\n const [plugin] = plugins.splice(ownIndex, 1);\n if (plugin) plugins.splice(astroIndex, 0, plugin);\n }\n },\n\n resolveId(id) {\n if (id.startsWith(VIRTUAL_PREFIX)) {\n return RESOLVED_VIRTUAL_PREFIX + id.slice(VIRTUAL_PREFIX.length);\n }\n return null;\n },\n\n async load(id) {\n if (!id.startsWith(RESOLVED_VIRTUAL_PREFIX)) return null;\n\n const publicId =\n VIRTUAL_PREFIX + id.slice(RESOLVED_VIRTUAL_PREFIX.length);\n const template = virtualModules.get(publicId);\n if (template === undefined) {\n throw new Error(`Missing flowview virtual module: ${publicId}`);\n }\n\n const { code } = await compileFlowview(template.source, {\n filename: template.filename,\n lineOffset: template.lineOffset,\n runtimeImport,\n compilerPath,\n });\n return code;\n },\n\n transform(code, id) {\n const cleanId = stripQuery(id);\n if (!cleanId.endsWith(\".astro\") || !code.includes(\"flowview\")) {\n return null;\n }\n\n try {\n return transformAstroSource(\n code,\n cleanId,\n virtualModules,\n virtualIdsByFile,\n );\n } catch (error) {\n if (error instanceof FlowviewAstroError) {\n const locatedError = {\n message: error.message,\n id: cleanId,\n loc: error.loc,\n };\n if (typeof this.error === \"function\") {\n this.error(locatedError);\n }\n throw locatedError;\n }\n throw error;\n }\n },\n };\n}\n\nfunction transformAstroSource(\n code: string,\n filename: string,\n virtualModules: Map<string, VirtualTemplate>,\n virtualIdsByFile: Map<string, Set<string>>,\n): { code: string; map: ReturnType<MagicString[\"generateMap\"]> } | null {\n const templates = findEmbeddedTemplates(code, filename);\n if (templates.length === 0) return null;\n\n const fileHash = createHash(\"sha256\")\n .update(filename)\n .digest(\"hex\")\n .slice(0, 12);\n const imports: string[] = [];\n const previousIds = virtualIdsByFile.get(filename);\n previousIds?.forEach((id) => virtualModules.delete(id));\n const currentIds = new Set<string>();\n const transformed = new MagicString(code);\n\n templates.forEach((template, index) => {\n const renderName = `__flowviewRender${index}`;\n const contentHash = createHash(\"sha256\")\n .update(template.source)\n .digest(\"hex\")\n .slice(0, 12);\n const virtualId = `${VIRTUAL_PREFIX}${fileHash}/${index}-${contentHash}.js`;\n virtualModules.set(virtualId, {\n source: template.source,\n filename,\n lineOffset: template.lineOffset,\n });\n currentIds.add(virtualId);\n imports.push(`import { render as ${renderName} } from \"${virtualId}\";`);\n transformed.overwrite(\n template.start,\n template.end,\n `<Fragment set:html={${renderName}(${template.contextExpression})} />`,\n );\n });\n\n virtualIdsByFile.set(filename, currentIds);\n injectFrontmatter(transformed, code, imports.join(\"\\n\"));\n\n return {\n code: transformed.toString(),\n map: transformed.generateMap({\n source: filename,\n includeContent: true,\n hires: true,\n }),\n };\n}\n\nfunction findEmbeddedTemplates(\n code: string,\n filename: string,\n): EmbeddedTemplate[] {\n const { ast } = parse(code, { position: true });\n const templates: EmbeddedTemplate[] = [];\n\n visitAstroNodes(ast, (node) => {\n if (!isTagNode(node) || node.name !== \"template\") return true;\n const flowviewAttribute = node.attributes.find(\n (attribute) => attribute.name === \"flowview\",\n );\n if (!flowviewAttribute) return true;\n\n const firstKnownOffset =\n flowviewAttribute.position?.start.offset ??\n node.position?.start.offset ??\n 0;\n const openStart = code.lastIndexOf(\"<\", firstKnownOffset);\n const openEnd = findTagEnd(code, openStart);\n if (openStart === -1 || openEnd === -1) {\n throw new FlowviewAstroError(\n \"flowview embedded template has an invalid opening tag.\",\n filename,\n firstKnownOffset,\n code,\n );\n }\n\n const contextAttribute = node.attributes.find(\n (attribute) => attribute.name === \"context\",\n );\n const flowviewExpression =\n flowviewAttribute.kind === \"expression\"\n ? flowviewAttribute.value.trim()\n : \"\";\n const contextExpression =\n flowviewExpression !== \"\"\n ? flowviewExpression\n : contextAttribute?.kind === \"expression\"\n ? contextAttribute.value.trim()\n : \"\";\n if (!contextExpression) {\n throw new FlowviewAstroError(\n \"flowview embedded templates require a context expression: flowview={...} or context={...}.\",\n filename,\n openStart,\n code,\n );\n }\n if (flowviewExpression !== \"\" && contextAttribute?.kind === \"expression\") {\n throw new FlowviewAstroError(\n \"flowview embedded templates must not combine flowview={...} with context={...}; use one of them.\",\n filename,\n openStart,\n code,\n );\n }\n\n const closeStart = findMatchingTemplateClose(code, openEnd + 1);\n if (closeStart === -1) {\n throw new FlowviewAstroError(\n \"flowview embedded template is missing </template>.\",\n filename,\n openStart,\n code,\n );\n }\n const closeTagEnd = findTagEnd(code, closeStart);\n if (closeTagEnd === -1) {\n throw new FlowviewAstroError(\n \"flowview embedded template has an invalid closing tag.\",\n filename,\n closeStart,\n code,\n );\n }\n\n templates.push({\n source: code.slice(openEnd + 1, closeStart),\n contextExpression,\n start: openStart,\n end: closeTagEnd + 1,\n lineOffset: countNewlines(code, 0, openEnd + 1),\n });\n\n return false;\n });\n\n return templates.sort((left, right) => left.start - right.start);\n}\n\nfunction visitAstroNodes(\n root: ParentLikeNode,\n visitor: (node: AstroNode) => boolean,\n): void {\n for (const child of root.children) {\n const shouldVisitChildren = visitor(child);\n if (shouldVisitChildren && \"children\" in child) {\n visitAstroNodes(child, visitor);\n }\n }\n}\n\nfunction isTagNode(node: AstroNode): node is TagLikeNode {\n return [\"element\", \"component\", \"custom-element\", \"fragment\"].includes(\n node.type,\n );\n}\n\nfunction findMatchingTemplateClose(code: string, start: number): number {\n let cursor = start;\n let depth = 1;\n\n while (cursor < code.length) {\n const tagStart = code.indexOf(\"<\", cursor);\n if (tagStart === -1) return -1;\n\n if (startsWithIgnoreCase(code, \"<!--\", tagStart)) {\n const commentEnd = code.indexOf(\"-->\", tagStart + 4);\n if (commentEnd === -1) return -1;\n cursor = commentEnd + 3;\n continue;\n }\n\n const rawTextTag = [\"script\", \"style\"].find(\n (name) =>\n startsWithIgnoreCase(code, `<${name}`, tagStart) &&\n isTagNameBoundary(code[tagStart + name.length + 1]),\n );\n if (rawTextTag !== undefined) {\n const closeStart = findCaseInsensitive(\n code,\n `</${rawTextTag}>`,\n tagStart + 1,\n );\n if (closeStart === -1) return -1;\n cursor = closeStart + rawTextTag.length + 3;\n continue;\n }\n\n if (\n startsWithIgnoreCase(code, \"<template\", tagStart) &&\n isTagNameBoundary(code[tagStart + \"<template\".length])\n ) {\n const tagEnd = findTagEnd(code, tagStart);\n if (tagEnd === -1) return -1;\n depth += 1;\n cursor = tagEnd + 1;\n continue;\n }\n\n if (\n startsWithIgnoreCase(code, \"</template\", tagStart) &&\n isTagNameBoundary(code[tagStart + \"</template\".length])\n ) {\n const tagEnd = findTagEnd(code, tagStart);\n if (tagEnd === -1) return -1;\n depth -= 1;\n if (depth === 0) return tagStart;\n cursor = tagEnd + 1;\n continue;\n }\n\n cursor = tagStart + 1;\n }\n\n return -1;\n}\n\nfunction findTagEnd(code: string, start: number): number {\n let quote: string | null = null;\n let braceDepth = 0;\n\n for (let index = start; index < code.length; index += 1) {\n const character = code[index];\n if (quote !== null) {\n if (character === \"\\\\\") index += 1;\n else if (character === quote) quote = null;\n continue;\n }\n if (character === '\"' || character === \"'\" || character === \"`\") {\n quote = character;\n } else if (character === \"{\") {\n braceDepth += 1;\n } else if (character === \"}\") {\n braceDepth = Math.max(0, braceDepth - 1);\n } else if (character === \">\" && braceDepth === 0) {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction injectFrontmatter(\n transformed: MagicString,\n original: string,\n content: string,\n): void {\n const closingFence = findFrontmatterClose(original);\n if (closingFence !== -1) {\n transformed.appendLeft(closingFence, `${content}\\n`);\n } else {\n transformed.prepend(`---\\n${content}\\n---\\n\\n`);\n }\n}\n\nfunction findFrontmatterClose(code: string): number {\n const firstLineEnd = code.indexOf(\"\\n\");\n if (firstLineEnd === -1 || code.slice(0, firstLineEnd).trim() !== \"---\") {\n return -1;\n }\n\n let lineStart = firstLineEnd + 1;\n while (lineStart <= code.length) {\n const lineEnd = code.indexOf(\"\\n\", lineStart);\n const end = lineEnd === -1 ? code.length : lineEnd;\n if (code.slice(lineStart, end).trim() === \"---\") return lineStart;\n if (lineEnd === -1) break;\n lineStart = lineEnd + 1;\n }\n\n return -1;\n}\n\nfunction isTagNameBoundary(character: string | undefined): boolean {\n return character === undefined || /[\\s/>]/.test(character);\n}\n\nfunction countNewlines(value: string, start: number, end: number): number {\n let count = 0;\n for (let index = start; index < end; index += 1) {\n if (value[index] === \"\\n\") count += 1;\n }\n return count;\n}\n\nfunction lineAndColumn(\n source: string,\n offset: number,\n): { line: number; column: number } {\n let line = 1;\n let column = 1;\n for (let index = 0; index < offset && index < source.length; index += 1) {\n if (source[index] === \"\\n\") {\n line += 1;\n column = 1;\n } else {\n column += 1;\n }\n }\n return { line, column };\n}\n\nfunction startsWithIgnoreCase(\n value: string,\n prefix: string,\n start = 0,\n): boolean {\n return (\n value.slice(start, start + prefix.length).toLowerCase() ===\n prefix.toLowerCase()\n );\n}\n\nfunction findCaseInsensitive(value: string, search: string, start = 0): number {\n const lowerSearch = search.toLowerCase();\n for (let index = start; index <= value.length - search.length; index += 1) {\n if (\n value.slice(index, index + search.length).toLowerCase() === lowerSearch\n ) {\n return index;\n }\n }\n return -1;\n}\n\nfunction stripQuery(id: string): string {\n return id.split(\"?\", 1)[0] ?? id;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flowview/astro",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Astro integration for flowview templates.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/andersseen/flowview.git",
|
|
11
|
+
"directory": "packages/astro"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/andersseen/flowview/issues"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/andersseen/flowview/tree/main/packages/astro#readme",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"flowview",
|
|
19
|
+
"astro",
|
|
20
|
+
"template",
|
|
21
|
+
"compiler",
|
|
22
|
+
"integration"
|
|
23
|
+
],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@astrojs/compiler": "^2.13.1",
|
|
38
|
+
"magic-string": "^0.30.21",
|
|
39
|
+
"@flowview/runtime": "^0.1.1",
|
|
40
|
+
"@flowview/vite": "^0.1.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^26.0.0",
|
|
44
|
+
"astro": "^5.7.10",
|
|
45
|
+
"tsup": "^8.5.0",
|
|
46
|
+
"typescript": "^5.9.0",
|
|
47
|
+
"vite": "^6.0.0",
|
|
48
|
+
"vitest": "^3.0.0"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"astro": "^5.0.0"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsup",
|
|
55
|
+
"test": "vitest run",
|
|
56
|
+
"typecheck": "tsc --noEmit"
|
|
57
|
+
}
|
|
58
|
+
}
|