Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,3 @@ npm run build:dev

We use a docker image in our CI/CD pipeline for building. This can be used locally, see
[Compiler README.md](./compiler/README.md)

## Testing

Coming soon... 🚀
9 changes: 9 additions & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export default defineConfig({
label: 'Serving a static site',
link: `${import.meta.env.BASE_URL}guides/serving-a-static-site/`,
},
{
label: 'Creating static assets',
link: `${import.meta.env.BASE_URL}guides/creating-a-static-manifest/`,
},
],
collapsed: true,
},
Expand All @@ -45,6 +49,11 @@ export default defineConfig({
collapsed: true,
autogenerate: { directory: 'reference' },
},
{
label: 'Migrating',
collapsed: true,
autogenerate: { directory: 'migrating' },
},
],
}),
],
Expand Down
76 changes: 76 additions & 0 deletions docs/src/content/docs/guides/creating-a-static-manifest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: Creating a Static Asset Manifest
description: How to generate a static-asset-manifest for creating Static Servers.
---

Apart from using `npx fastedge-init` to create Static Sites you can also access the built-in tools
directly.

`npx fastedge-init` is using this concept under the hood.

## Static files

Because the `wasm` runtime has no concept of a file system we are unable to serve static files in
the normal manner.

To solve for this we are able to read files at `compile` time and store them within the wasm binary
itself as a UintArrayBuffer.

For this purpose the FastEdge-sdk-js provides a `npx fastedge-assets` command.

### fastedge-assets

This command takes an input folder and an output filename.

e.g.

```sh
npx fastedge-assets ./public ./src/public-static-assets.ts
```

It then creates a "Static Assets Manifest" file which is a mapping of all files to include within
the binary at compile time. (i.e. all files within the `/public` directory)

Simplified example:

```js
const staticAssetManifest = {
'/gcore.png': {
assetKey: '/gcore.png',
contentType: 'image/png',
fileInfo: { size: 40261, assetPath: './images/gcore.png' },
type: 'wasm-inline',
},
'/home.png': {
assetKey: '/home.png',
contentType: 'image/png',
fileInfo: { size: 1502064, assetPath: './images/home.png' },
type: 'wasm-inline',
},
};

export { staticAssetManifest };
```

This `manifest` can then be consumed by creating a Static Server using:

```js
import { createStaticServer } from '@gcoredev/fastedge-sdk-js';

createStaticServer(staticAssetManifest, serverConfig);
```

Because
<a href='https://github.com/bytecodealliance/wizer' target='_blank' rel='noopener noreferrer'>wizer</a>
runs all top-level code before taking a snapshot, you need to ensure that `createStaticServer()` is
called within the main file at the top level. It cannot be nested in functions or async code that
may not run during compilation.

This ensures that `staticAssetManifest` is iterated over and all files read into wasm memory. After
which `wizer` snapshots the current state, and creates the final wasm binary with all the file
contents included within the memory at startup. This process ensures there is **NO** start-up delay
and all files are available at runtime.

There is a more complete example in our
<a href='https://github.com/G-Core/FastEdge-examples/blob/main/javascript/README.md' target='_blank' rel='noopener noreferrer'>FastEdge-examples</a>
repo.
72 changes: 72 additions & 0 deletions docs/src/content/docs/migrating/v1-v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
title: Version 1.x.x > 2.x.x
description: Breaking changes in FastEdge-sdk-js@2.0.0
---

### Static Asset Servers

The way Static Asset Manifests are consumed has changed.

The new version allows for multiple manifests within the same application as well as the ability to
read file content as a string.

The easiest way for most people to make this migration is to purely re-run:

```sh
npx fastedge-init
```

Unless you have custom written code using these functions, the default `static-index.js` should be
updated automatically for you.

Version 1:

```ts
import { getStaticServer, createStaticAssetsCache } from '@gcoredev/fastedge-sdk-js';
import { staticAssetManifest } from './build/static-server-manifest.js';
import { serverConfig } from './build-config.js';

const staticAssets = createStaticAssetsCache(staticAssetManifest);

const staticServer = getStaticServer(serverConfig, staticAssets);

async function handleRequest(event) {
const response = await staticServer.serveRequest(event.request);
if (response != null) {
return response;
}

return new Response('Not found', { status: 404 });
}

addEventListener('fetch', (event) => event.respondWith(handleRequest(event)));
```

Version 2:

```ts
import { createStaticServer } from '@gcoredev/fastedge-sdk-js';
import { staticAssetManifest } from './build/static-asset-manifest.js';
import { serverConfig } from './build-config.js';

const staticServer = createStaticServer(staticAssetManifest, serverConfig);

async function handleRequest(event) {
const response = await staticServer.serveRequest(event.request);
if (response != null) {
return response;
}

return new Response('Not found', { status: 404 });
}

addEventListener('fetch', (event) => event.respondWith(handleRequest(event)));
```

:::note[INFO]

For more examples about the new version see our
<a href='https://github.com/G-Core/FastEdge-examples/blob/main/javascript/README.md' target='_blank' rel='noopener noreferrer'>FastEdge-examples</a>
repo.

:::
3 changes: 2 additions & 1 deletion esbuild/cli-binaries.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fileURLToPath } from "node:url";
import path from "node:path";
import { readFileSync, writeFileSync } from "node:fs";

const entryPoints = [
const entryPoints = [
{ src: "./src/cli/fastedge-assets/asset-cli.ts", dest: "./bin/fastedge-assets.js" },
{ src: "./src/cli/fastedge-build/build.ts", dest: "./bin/fastedge-build.js" },
{ src: "./src/cli/fastedge-init/init.ts", dest: "./bin/fastedge-init.js" },
Expand Down Expand Up @@ -50,5 +50,6 @@ const prependNodeShebangToFile = (relativeFilePath) => {
}
};

prependNodeShebangToFile("./bin/fastedge-assets.js");
prependNodeShebangToFile("./bin/fastedge-build.js");
prependNodeShebangToFile("./bin/fastedge-init.js");
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
},
"files": [
"types",
"bin/fastedge-assets.js",
"bin/fastedge-build.js",
"bin/fastedge-init.js",
"lib/*.wasm",
Expand Down
7 changes: 4 additions & 3 deletions src/utils/config-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
* @param str - The string to process.
* @returns The string without the './' prefix.
*/
const removeDotSlashPrefix = (str: string): string => str.replace(/^\.\//u, '');
const removeDotSlashPrefix = (str: string = ''): string => str.replace(/^\.\//u, '');

/**
* Removes trailing slashes from a given string.
* @param str - The string to process.
* @returns The string without trailing slashes.
*/
const removeTrailingSlash = (str: string): string => str.replace(/\/+$/u, '');
const removeTrailingSlash = (str: string = ''): string => str.replace(/\/+$/u, '');

/**
* Takes a path string and ensures it has no trailing slash and has a single preceding slash.
Expand Down Expand Up @@ -152,7 +152,8 @@ function normalizeConfig<T extends Record<string, unknown>>(
const normalizeFn = normalizeFns[normalizeFnKey];
if (normalizeFn) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
result[key] = normalizeFn(config[key] as any) as T[keyof T];
const input = (config[key] ?? undefined) as any;
result[key] = normalizeFn(input) as T[keyof T];
}
});

Expand Down