@microsoft/fast-build 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/README.md +103 -0
- package/bin/fast.js +255 -0
- package/get-package-json.js +25 -0
- package/package.json +36 -0
- package/wasm/microsoft_fast_build.d.ts +24 -0
- package/wasm/microsoft_fast_build.js +199 -0
- package/wasm/microsoft_fast_build_bg.wasm +0 -0
- package/wasm/microsoft_fast_build_bg.wasm.d.ts +12 -0
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# `@microsoft/fast-build`
|
|
2
|
+
|
|
3
|
+
Server-side renderer for [FAST](https://www.fast.design/) declarative HTML templates, powered by a WebAssembly core with zero runtime npm dependencies.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @microsoft/fast-build
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## CLI usage
|
|
12
|
+
|
|
13
|
+
Once installed, the `fast` binary is available. Use the `build` subcommand to render an HTML template with a JSON state file:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
fast build [options]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Options
|
|
20
|
+
|
|
21
|
+
| Option | Default | Description |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `--entry="<path>"` | `index.html` | Entry HTML template to render |
|
|
24
|
+
| `--state="<path>"` | `state.json` | JSON file containing the template state |
|
|
25
|
+
| `--output="<path>"` | `output.html` | Where to write the rendered HTML |
|
|
26
|
+
| `--templates="<glob>"` | _(none)_ | Glob pattern(s) for custom element template HTML files. Separate multiple patterns with commas. A warning is printed if not provided or if no files match a pattern. |
|
|
27
|
+
|
|
28
|
+
### Example
|
|
29
|
+
|
|
30
|
+
Given an `index.html`:
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<html>
|
|
34
|
+
<body>
|
|
35
|
+
<h1>{{title}}</h1>
|
|
36
|
+
<p>{{description}}</p>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
And a `state.json`:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"title": "Hello FAST",
|
|
46
|
+
"description": "Server-side rendered with WebAssembly."
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Run:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
fast build --entry=index.html --state=state.json --output=output.html
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Produces `output.html`:
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<html>
|
|
60
|
+
<body>
|
|
61
|
+
<h1>Hello FAST</h1>
|
|
62
|
+
<p>Server-side rendered with WebAssembly.</p>
|
|
63
|
+
</body>
|
|
64
|
+
</html>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Custom element templates
|
|
68
|
+
|
|
69
|
+
Pass a glob pattern (or comma-separated list of patterns) to `--templates` to expand custom elements into [Declarative Shadow DOM](https://developer.chrome.com/docs/css-ui/declarative-shadow-dom):
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
fast build \
|
|
73
|
+
--templates="./components/**/*.html" \
|
|
74
|
+
--entry=index.html \
|
|
75
|
+
--state=state.json \
|
|
76
|
+
--output=output.html
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Each matched `.html` file is scanned for `<f-template>` elements. The `name` attribute of each `<f-template>` determines the custom element name. A single file may contain multiple templates.
|
|
80
|
+
|
|
81
|
+
Template files must use the following format:
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<f-template name="my-button">
|
|
85
|
+
<template>
|
|
86
|
+
<button>{{label}}</button>
|
|
87
|
+
</template>
|
|
88
|
+
</f-template>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
If an `<f-template>` element has no `name` attribute, a warning is printed and it is ignored. Exact file paths (no wildcards) are also accepted as patterns, making it possible to register a single template file.
|
|
92
|
+
|
|
93
|
+
## Template syntax
|
|
94
|
+
|
|
95
|
+
Template syntax follows the FAST declarative HTML format. See the [`@microsoft/fast-html` README](../fast-html/README.md) for full documentation on bindings, conditionals, repeats, and directives.
|
|
96
|
+
|
|
97
|
+
## Contributing
|
|
98
|
+
|
|
99
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
[](https://opensource.org/licenses/MIT)
|
package/bin/fast.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-check
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
|
|
8
|
+
const WASM_MODULE = path.join(__dirname, "../wasm/microsoft_fast_build.js");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parse CLI arguments of the form --key="value" or --key=value.
|
|
12
|
+
* @param {string[]} argv
|
|
13
|
+
* @returns {Record<string, string>}
|
|
14
|
+
*/
|
|
15
|
+
function parseArgs(argv) {
|
|
16
|
+
const args = {};
|
|
17
|
+
for (const arg of argv) {
|
|
18
|
+
const match = arg.match(/^--([^=]+)=(.*)$/s);
|
|
19
|
+
if (match) {
|
|
20
|
+
args[match[1]] = match[2].replace(/^"|"$/g, "");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return args;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Walk a directory recursively and collect all .html file paths.
|
|
28
|
+
* @param {string} dir
|
|
29
|
+
* @param {string[]} results
|
|
30
|
+
*/
|
|
31
|
+
function walkHtmlFiles(dir, results) {
|
|
32
|
+
let entries;
|
|
33
|
+
try {
|
|
34
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
35
|
+
} catch {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
for (const entry of entries) {
|
|
39
|
+
const fullPath = path.join(dir, entry.name);
|
|
40
|
+
if (entry.isDirectory()) {
|
|
41
|
+
walkHtmlFiles(fullPath, results);
|
|
42
|
+
} else if (entry.isFile() && entry.name.endsWith(".html")) {
|
|
43
|
+
results.push(fullPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Match a normalized path against a glob pattern.
|
|
50
|
+
* Supports * (within one segment), ** (across segments), ? (single char).
|
|
51
|
+
* @param {string} pattern
|
|
52
|
+
* @param {string} filePath
|
|
53
|
+
* @returns {boolean}
|
|
54
|
+
*/
|
|
55
|
+
function globMatch(pattern, filePath) {
|
|
56
|
+
const normalize = (p) => p.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
57
|
+
const pat = normalize(pattern).split("/");
|
|
58
|
+
const file = normalize(filePath).split("/");
|
|
59
|
+
return matchSegments(pat, file);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** @param {string[]} pat @param {string[]} file @returns {boolean} */
|
|
63
|
+
function matchSegments(pat, file) {
|
|
64
|
+
if (pat.length === 0) return file.length === 0;
|
|
65
|
+
if (pat[0] === "**") {
|
|
66
|
+
if (matchSegments(pat.slice(1), file)) return true;
|
|
67
|
+
if (file.length > 0 && matchSegments(pat, file.slice(1))) return true;
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
if (file.length === 0) return false;
|
|
71
|
+
if (matchSegment(pat[0], file[0])) return matchSegments(pat.slice(1), file.slice(1));
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** @param {string} pat @param {string} seg @returns {boolean} */
|
|
76
|
+
function matchSegment(pat, seg) {
|
|
77
|
+
return matchChars([...pat], [...seg]);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** @param {string[]} pat @param {string[]} seg @returns {boolean} */
|
|
81
|
+
function matchChars(pat, seg) {
|
|
82
|
+
if (pat.length === 0) return seg.length === 0;
|
|
83
|
+
if (pat[0] === "*") {
|
|
84
|
+
for (let i = 0; i <= seg.length; i++) {
|
|
85
|
+
if (matchChars(pat.slice(1), seg.slice(i))) return true;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (seg.length === 0) return false;
|
|
90
|
+
if (pat[0] === "?" || pat[0] === seg[0]) return matchChars(pat.slice(1), seg.slice(1));
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Given a glob pattern, return the static directory prefix before the first wildcard.
|
|
96
|
+
* @param {string} pattern
|
|
97
|
+
* @returns {string}
|
|
98
|
+
*/
|
|
99
|
+
function staticPrefixDir(pattern) {
|
|
100
|
+
const norm = pattern.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
101
|
+
const firstWild = norm.search(/[*?]/);
|
|
102
|
+
if (firstWild === -1) {
|
|
103
|
+
const lastSlash = norm.lastIndexOf("/");
|
|
104
|
+
return lastSlash >= 0 ? norm.slice(0, lastSlash + 1) : ".";
|
|
105
|
+
}
|
|
106
|
+
const before = norm.slice(0, firstWild);
|
|
107
|
+
const lastSlash = before.lastIndexOf("/");
|
|
108
|
+
return lastSlash >= 0 ? before.slice(0, lastSlash + 1) : ".";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Parse all `<f-template>` elements from an HTML string using the WASM module.
|
|
113
|
+
* Returns [{name, content}] for templates that have a `name` attribute.
|
|
114
|
+
* Emits a warning to stderr for any `<f-template>` without a `name`.
|
|
115
|
+
* @param {string} html
|
|
116
|
+
* @param {string} filePath - used in warning messages
|
|
117
|
+
* @param {object} wasm - the loaded WASM module
|
|
118
|
+
* @returns {{ name: string, content: string }[]}
|
|
119
|
+
*/
|
|
120
|
+
function parseFTemplates(html, filePath, wasm) {
|
|
121
|
+
/** @type {{ name: string | null, content: string }[]} */
|
|
122
|
+
const parsed = JSON.parse(wasm.parse_f_templates(html));
|
|
123
|
+
const results = [];
|
|
124
|
+
for (const { name, content } of parsed) {
|
|
125
|
+
if (name === null) {
|
|
126
|
+
process.stderr.write(
|
|
127
|
+
`Warning: <f-template> without a 'name' attribute in '${filePath}': ${content.trim()}\n`
|
|
128
|
+
);
|
|
129
|
+
} else {
|
|
130
|
+
results.push({ name, content });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return results;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Resolve all HTML files matching a glob pattern.
|
|
138
|
+
* Parses `<f-template name="...">` elements from each matched file and
|
|
139
|
+
* returns one entry per template. A single file may yield multiple entries.
|
|
140
|
+
* Warns (but does not error) if the base directory does not exist.
|
|
141
|
+
* @param {string} pattern
|
|
142
|
+
* @param {object} wasm - the loaded WASM module
|
|
143
|
+
* @returns {{ name: string, content: string }[]}
|
|
144
|
+
*/
|
|
145
|
+
function resolvePattern(pattern, wasm) {
|
|
146
|
+
const baseDir = staticPrefixDir(pattern);
|
|
147
|
+
if (!fs.existsSync(baseDir)) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
const allFiles = [];
|
|
151
|
+
walkHtmlFiles(baseDir, allFiles);
|
|
152
|
+
const results = [];
|
|
153
|
+
for (const file of allFiles) {
|
|
154
|
+
if (globMatch(pattern, file)) {
|
|
155
|
+
const html = fs.readFileSync(file, "utf8");
|
|
156
|
+
const templates = parseFTemplates(html, file, wasm);
|
|
157
|
+
for (const { name, content } of templates) {
|
|
158
|
+
results.push({ name, content });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return results;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function runBuild(args) {
|
|
166
|
+
const templatesArg = args["templates"];
|
|
167
|
+
const output = args["output"] || "output.html";
|
|
168
|
+
const entry = args["entry"] || "index.html";
|
|
169
|
+
const stateFile = args["state"] || "state.json";
|
|
170
|
+
|
|
171
|
+
// Load WASM module first — needed for both template parsing and rendering.
|
|
172
|
+
const wasm = require(WASM_MODULE);
|
|
173
|
+
|
|
174
|
+
// Resolve template files
|
|
175
|
+
const templatesMap = {};
|
|
176
|
+
if (!templatesArg) {
|
|
177
|
+
process.stderr.write(
|
|
178
|
+
"Warning: --templates was not provided. No custom element templates will be loaded.\n"
|
|
179
|
+
);
|
|
180
|
+
} else {
|
|
181
|
+
const patterns = templatesArg.split(",").map((p) => p.trim());
|
|
182
|
+
for (const pattern of patterns) {
|
|
183
|
+
const matches = resolvePattern(pattern, wasm);
|
|
184
|
+
if (matches.length === 0) {
|
|
185
|
+
process.stderr.write(
|
|
186
|
+
`Warning: No template files found for pattern "${pattern}".\n`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
for (const { name, content } of matches) {
|
|
190
|
+
if (name in templatesMap) {
|
|
191
|
+
process.stderr.write(
|
|
192
|
+
`Warning: Duplicate template name "${name}" — later file overwrites earlier.\n`
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
templatesMap[name] = content;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Read entry file
|
|
201
|
+
if (!fs.existsSync(entry)) {
|
|
202
|
+
process.stderr.write(`Error: Entry file "${entry}" not found.\n`);
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
const entryContent = fs.readFileSync(entry, "utf8");
|
|
206
|
+
|
|
207
|
+
// Read state file
|
|
208
|
+
if (!fs.existsSync(stateFile)) {
|
|
209
|
+
process.stderr.write(`Error: State file "${stateFile}" not found.\n`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
const stateContent = fs.readFileSync(stateFile, "utf8");
|
|
213
|
+
|
|
214
|
+
// Render
|
|
215
|
+
let rendered;
|
|
216
|
+
if (Object.keys(templatesMap).length > 0) {
|
|
217
|
+
rendered = wasm.render_with_templates(entryContent, JSON.stringify(templatesMap), stateContent);
|
|
218
|
+
} else {
|
|
219
|
+
rendered = wasm.render(entryContent, stateContent);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Write output
|
|
223
|
+
fs.writeFileSync(output, rendered, "utf8");
|
|
224
|
+
process.stdout.write(`Built: ${output}\n`);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function main() {
|
|
228
|
+
const argv = process.argv.slice(2);
|
|
229
|
+
if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
|
|
230
|
+
process.stdout.write(
|
|
231
|
+
"Usage: fast build [options]\n\n" +
|
|
232
|
+
"Options:\n" +
|
|
233
|
+
' --templates="<glob>" Glob pattern(s) for custom element template HTML files.\n' +
|
|
234
|
+
' Separate multiple patterns with commas.\n' +
|
|
235
|
+
' --output="output.html" Output file path (default: output.html)\n' +
|
|
236
|
+
' --entry="index.html" Entry HTML template file (default: index.html)\n' +
|
|
237
|
+
' --state="state.json" State JSON file (default: state.json)\n'
|
|
238
|
+
);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const subcommand = argv[0];
|
|
243
|
+
if (subcommand !== "build") {
|
|
244
|
+
process.stderr.write(`Unknown subcommand: "${subcommand}". Expected "build".\n`);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const args = parseArgs(argv.slice(1));
|
|
249
|
+
await runBuild(args);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
main().catch((err) => {
|
|
253
|
+
process.stderr.write(`Error: ${err.message || err}\n`);
|
|
254
|
+
process.exit(1);
|
|
255
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolves the directory of the package.json for a given dependency.
|
|
6
|
+
* @param {string} name - the package name
|
|
7
|
+
* @returns
|
|
8
|
+
*
|
|
9
|
+
* @description
|
|
10
|
+
* NodeJS exports fields prevent arbitrarily resolving files in a package
|
|
11
|
+
* that are not explicitly enumerated in the exports field of the package.
|
|
12
|
+
* This function provides a mechanism to resolve the package 'root' by package name,
|
|
13
|
+
* allowing file-system retrieval by relative path for arbitrary files outside of
|
|
14
|
+
* Node's module system.
|
|
15
|
+
*/
|
|
16
|
+
exports.getPackageJsonDir = (name, options) => {
|
|
17
|
+
const entry = require.resolve(name, options).toString();
|
|
18
|
+
let dir = path.parse(entry).dir;
|
|
19
|
+
|
|
20
|
+
while (!fs.existsSync(path.resolve(dir, "package.json"))) {
|
|
21
|
+
dir = path.parse(dir).dir;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return dir;
|
|
25
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@microsoft/fast-build",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "CLI and Node.js API for server-side rendering of FAST declarative HTML templates.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Microsoft",
|
|
7
|
+
"url": "https://discord.gg/FcSNfg4"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://www.fast.design/",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/Microsoft/fast.git",
|
|
14
|
+
"directory": "packages/fast-build"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/microsoft/fast/issues/new/choose"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"fast": "./bin/fast.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"bin",
|
|
24
|
+
"get-package-json.js",
|
|
25
|
+
"wasm/microsoft_fast_build.js",
|
|
26
|
+
"wasm/microsoft_fast_build_bg.wasm",
|
|
27
|
+
"wasm/microsoft_fast_build.d.ts",
|
|
28
|
+
"wasm/microsoft_fast_build_bg.wasm.d.ts"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build:wasm": "wasm-pack build --target nodejs ../../crates/microsoft-fast-build --out-dir ../../packages/fast-build/wasm"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=22.18.0"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parse all `<f-template>` elements from an HTML string.
|
|
6
|
+
* Returns a JSON array of `{"name": string | null, "content": string}` objects,
|
|
7
|
+
* one per `<f-template>` element found. `name` is `null` when the element has
|
|
8
|
+
* no `name` attribute.
|
|
9
|
+
*/
|
|
10
|
+
export function parse_f_templates(html: string): string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Render a FAST HTML template with a JSON state string.
|
|
14
|
+
* Returns the rendered HTML or throws a JavaScript error.
|
|
15
|
+
*/
|
|
16
|
+
export function render(entry: string, state: string): string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Render a FAST HTML template with custom element templates and a JSON state string.
|
|
20
|
+
* `templates_json` is a JSON object mapping element names to their HTML template strings,
|
|
21
|
+
* e.g. `{"my-button": "<template>...</template>"}`.
|
|
22
|
+
* Returns the rendered HTML or throws a JavaScript error.
|
|
23
|
+
*/
|
|
24
|
+
export function render_with_templates(entry: string, templates_json: string, state: string): string;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/* @ts-self-types="./microsoft_fast_build.d.ts" */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parse all `<f-template>` elements from an HTML string.
|
|
5
|
+
* Returns a JSON array of `{"name": string | null, "content": string}` objects,
|
|
6
|
+
* one per `<f-template>` element found. `name` is `null` when the element has
|
|
7
|
+
* no `name` attribute.
|
|
8
|
+
* @param {string} html
|
|
9
|
+
* @returns {string}
|
|
10
|
+
*/
|
|
11
|
+
function parse_f_templates(html) {
|
|
12
|
+
let deferred2_0;
|
|
13
|
+
let deferred2_1;
|
|
14
|
+
try {
|
|
15
|
+
const ptr0 = passStringToWasm0(html, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
16
|
+
const len0 = WASM_VECTOR_LEN;
|
|
17
|
+
const ret = wasm.parse_f_templates(ptr0, len0);
|
|
18
|
+
deferred2_0 = ret[0];
|
|
19
|
+
deferred2_1 = ret[1];
|
|
20
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
21
|
+
} finally {
|
|
22
|
+
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.parse_f_templates = parse_f_templates;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Render a FAST HTML template with a JSON state string.
|
|
29
|
+
* Returns the rendered HTML or throws a JavaScript error.
|
|
30
|
+
* @param {string} entry
|
|
31
|
+
* @param {string} state
|
|
32
|
+
* @returns {string}
|
|
33
|
+
*/
|
|
34
|
+
function render(entry, state) {
|
|
35
|
+
let deferred4_0;
|
|
36
|
+
let deferred4_1;
|
|
37
|
+
try {
|
|
38
|
+
const ptr0 = passStringToWasm0(entry, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
39
|
+
const len0 = WASM_VECTOR_LEN;
|
|
40
|
+
const ptr1 = passStringToWasm0(state, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
41
|
+
const len1 = WASM_VECTOR_LEN;
|
|
42
|
+
const ret = wasm.render(ptr0, len0, ptr1, len1);
|
|
43
|
+
var ptr3 = ret[0];
|
|
44
|
+
var len3 = ret[1];
|
|
45
|
+
if (ret[3]) {
|
|
46
|
+
ptr3 = 0; len3 = 0;
|
|
47
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
48
|
+
}
|
|
49
|
+
deferred4_0 = ptr3;
|
|
50
|
+
deferred4_1 = len3;
|
|
51
|
+
return getStringFromWasm0(ptr3, len3);
|
|
52
|
+
} finally {
|
|
53
|
+
wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.render = render;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Render a FAST HTML template with custom element templates and a JSON state string.
|
|
60
|
+
* `templates_json` is a JSON object mapping element names to their HTML template strings,
|
|
61
|
+
* e.g. `{"my-button": "<template>...</template>"}`.
|
|
62
|
+
* Returns the rendered HTML or throws a JavaScript error.
|
|
63
|
+
* @param {string} entry
|
|
64
|
+
* @param {string} templates_json
|
|
65
|
+
* @param {string} state
|
|
66
|
+
* @returns {string}
|
|
67
|
+
*/
|
|
68
|
+
function render_with_templates(entry, templates_json, state) {
|
|
69
|
+
let deferred5_0;
|
|
70
|
+
let deferred5_1;
|
|
71
|
+
try {
|
|
72
|
+
const ptr0 = passStringToWasm0(entry, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
73
|
+
const len0 = WASM_VECTOR_LEN;
|
|
74
|
+
const ptr1 = passStringToWasm0(templates_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
75
|
+
const len1 = WASM_VECTOR_LEN;
|
|
76
|
+
const ptr2 = passStringToWasm0(state, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
77
|
+
const len2 = WASM_VECTOR_LEN;
|
|
78
|
+
const ret = wasm.render_with_templates(ptr0, len0, ptr1, len1, ptr2, len2);
|
|
79
|
+
var ptr4 = ret[0];
|
|
80
|
+
var len4 = ret[1];
|
|
81
|
+
if (ret[3]) {
|
|
82
|
+
ptr4 = 0; len4 = 0;
|
|
83
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
84
|
+
}
|
|
85
|
+
deferred5_0 = ptr4;
|
|
86
|
+
deferred5_1 = len4;
|
|
87
|
+
return getStringFromWasm0(ptr4, len4);
|
|
88
|
+
} finally {
|
|
89
|
+
wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.render_with_templates = render_with_templates;
|
|
93
|
+
|
|
94
|
+
function __wbg_get_imports() {
|
|
95
|
+
const import0 = {
|
|
96
|
+
__proto__: null,
|
|
97
|
+
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
98
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
99
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
100
|
+
return ret;
|
|
101
|
+
},
|
|
102
|
+
__wbindgen_init_externref_table: function() {
|
|
103
|
+
const table = wasm.__wbindgen_externrefs;
|
|
104
|
+
const offset = table.grow(4);
|
|
105
|
+
table.set(0, undefined);
|
|
106
|
+
table.set(offset + 0, undefined);
|
|
107
|
+
table.set(offset + 1, null);
|
|
108
|
+
table.set(offset + 2, true);
|
|
109
|
+
table.set(offset + 3, false);
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
return {
|
|
113
|
+
__proto__: null,
|
|
114
|
+
"./microsoft_fast_build_bg.js": import0,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function getStringFromWasm0(ptr, len) {
|
|
119
|
+
ptr = ptr >>> 0;
|
|
120
|
+
return decodeText(ptr, len);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let cachedUint8ArrayMemory0 = null;
|
|
124
|
+
function getUint8ArrayMemory0() {
|
|
125
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
126
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
127
|
+
}
|
|
128
|
+
return cachedUint8ArrayMemory0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
132
|
+
if (realloc === undefined) {
|
|
133
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
134
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
135
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
136
|
+
WASM_VECTOR_LEN = buf.length;
|
|
137
|
+
return ptr;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let len = arg.length;
|
|
141
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
142
|
+
|
|
143
|
+
const mem = getUint8ArrayMemory0();
|
|
144
|
+
|
|
145
|
+
let offset = 0;
|
|
146
|
+
|
|
147
|
+
for (; offset < len; offset++) {
|
|
148
|
+
const code = arg.charCodeAt(offset);
|
|
149
|
+
if (code > 0x7F) break;
|
|
150
|
+
mem[ptr + offset] = code;
|
|
151
|
+
}
|
|
152
|
+
if (offset !== len) {
|
|
153
|
+
if (offset !== 0) {
|
|
154
|
+
arg = arg.slice(offset);
|
|
155
|
+
}
|
|
156
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
157
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
158
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
159
|
+
|
|
160
|
+
offset += ret.written;
|
|
161
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
WASM_VECTOR_LEN = offset;
|
|
165
|
+
return ptr;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function takeFromExternrefTable0(idx) {
|
|
169
|
+
const value = wasm.__wbindgen_externrefs.get(idx);
|
|
170
|
+
wasm.__externref_table_dealloc(idx);
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
175
|
+
cachedTextDecoder.decode();
|
|
176
|
+
function decodeText(ptr, len) {
|
|
177
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const cachedTextEncoder = new TextEncoder();
|
|
181
|
+
|
|
182
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
183
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
184
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
185
|
+
view.set(buf);
|
|
186
|
+
return {
|
|
187
|
+
read: arg.length,
|
|
188
|
+
written: buf.length
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
let WASM_VECTOR_LEN = 0;
|
|
194
|
+
|
|
195
|
+
const wasmPath = `${__dirname}/microsoft_fast_build_bg.wasm`;
|
|
196
|
+
const wasmBytes = require('fs').readFileSync(wasmPath);
|
|
197
|
+
const wasmModule = new WebAssembly.Module(wasmBytes);
|
|
198
|
+
let wasm = new WebAssembly.Instance(wasmModule, __wbg_get_imports()).exports;
|
|
199
|
+
wasm.__wbindgen_start();
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export const memory: WebAssembly.Memory;
|
|
4
|
+
export const parse_f_templates: (a: number, b: number) => [number, number];
|
|
5
|
+
export const render: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
6
|
+
export const render_with_templates: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number, number];
|
|
7
|
+
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
8
|
+
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
9
|
+
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
10
|
+
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
11
|
+
export const __externref_table_dealloc: (a: number) => void;
|
|
12
|
+
export const __wbindgen_start: () => void;
|