Skip to content

@gameable/vite-plugin-gameable ​

Interfaces ​

EmitContext ​

The slice of the Rollup plugin context the plugin uses.

Methods ​

emitFile() ​
ts
emitFile(asset): void;

Emit one asset into the build.

Parameters ​
ParameterTypeDescription
asset{ fileName: string; source: string | Uint8Array<ArrayBufferLike>; type: "asset"; }The asset descriptor.
asset.fileNamestring-
asset.sourcestring | Uint8Array<ArrayBufferLike>-
asset.type"asset"-
Returns ​

void

warn() ​
ts
warn(message): void;

Report a build-time warning.

Parameters ​
ParameterTypeDescription
messagestringWhat to say.
Returns ​

void


GameableConfig ​

The configuration gameable() contributes, as a plain object.

Properties ​

alias ​
ts
alias: object[];

Alias entries to add, in Vite's array form.

find ​
ts
find: RegExp;
replacement ​
ts
replacement: string;
conditions ​
ts
conditions: string[];

Resolve conditions to add.

define ​
ts
define: Record<string, string>;

define entries, including import.meta.env.GAMEABLE_MODE.

exclude ​
ts
exclude: string[];

Packages to keep out of the dependency pre-bundle.

guestBase ​
ts
guestBase: string;

Path the guest is served from, with a leading and trailing slash.

guestOutDir ​
ts
guestOutDir: string;

Where the guest lands inside the build output, relative to outDir, with a trailing slash and no leading one. This is guestBase minus the app base: an emitted file is named relative to outDir, and the base is what the server puts in front of outDir, so baking it into the file name would serve the guest from <base><base>guest/.

guestUrl ​
ts
guestUrl: string;

URL of the transpiled guest entry, as the app should fetch it.

mode ​
ts
mode: GameableMode;

The sandbox mode the app was built for.


GameableEnv ​

The environment resolveGameableConfig reads.

Properties ​

base? ​
ts
optional base?: string;

The app's public base path, as Vite resolved it. Defaults to /.

command ​
ts
command: "serve" | "build";

Vite's command: serve for dev and preview, build for a production build.

env? ​
ts
optional env?: Record<string, string | undefined>;

Process environment, for GAMEABLE_MODE and GAMEABLE_WASM.

viteMode? ​
ts
optional viteMode?: string;

Vite's own --mode. direct and wasm select the sandbox, which is how vite build --mode direct produces a build that needs no guest component.


GameableOptions ​

Options accepted by gameable.

Properties ​

development? ​
ts
optional development?: boolean;

The old name of source, from when the condition was development.

exclude? ​
ts
optional exclude?: readonly string[];

Extra package names kept out of the dependency pre-bundle. The wasm runtimes jolt-physics and onnxruntime-web are always excluded.

guestBase? ​
ts
optional guestBase?: string;

Path the guest is served from, relative to the app base. Defaults to guest/; the transpiled entry is then guest/game.js.

guestDir? ​
ts
optional guestDir?: string;

Directory holding the jco transpile output, relative to the Vite root. Defaults to build/guest, which is where scripts/build-guest.mjs writes.

guestSources? ​
ts
optional guestSources?: readonly string[];

What the guest is built from, relative to the Vite root, for the dev server's stale-guest answer. Defaults to src/, scripts/build-guest.mjs and the SDK's sources (guestSources).

mode? ​
ts
optional mode?: GameableMode;

Force a sandbox mode instead of deriving one.

The derivation, in order: this option, then Vite's own --mode when it is direct or wasm, then GAMEABLE_MODE in the environment, then GAMEABLE_WASM=1, then wasm for vite build and direct for vite dev.

source? ​
ts
optional source?: boolean;

Add the gameable-source resolve condition, so the engine's packages resolve to their sources in this repository. Defaults to true.

three? ​
ts
optional three?: boolean;

Alias bare three onto three/webgpu. Defaults to true.


GameableVitePlugin ​

The shape of the Vite plugin object this package produces.

Typed structurally rather than as Vite's Plugin so the package carries no runtime or type dependency on a particular Vite major; a real Vite accepts it because every member matches.

Properties ​

enforce? ​
ts
optional enforce?: "pre" | "post";

Run before Vite's own resolution, so the alias and conditions win.

name ​
ts
name: string;

Plugin name, as it appears in Vite's logs.

Methods ​

config()? ​
ts
optional config(config, env): unknown;

Contribute configuration.

Parameters ​
ParameterTypeDescription
configRecord<string, unknown>The user's configuration so far.
env{ command: "serve" | "build"; mode?: string; }Vite's command and mode.
env.command"serve" | "build"-
env.mode?string-
Returns ​

unknown

A partial configuration Vite deep-merges.

configResolved()? ​
ts
optional configResolved(config): void;

Record the base Vite resolved, so the guest URL is right under a sub-path.

Parameters ​
ParameterTypeDescription
config{ base?: string; root?: string; }The resolved configuration.
config.base?string-
config.root?string-
Returns ​

void

configureServer()? ​
ts
optional configureServer(server): void;

Install the dev middlewares.

Parameters ​
ParameterTypeDescription
server{ middlewares: { use: (fn) => void; }; }The dev server.
server.middlewares{ use: (fn) => void; }-
server.middlewares.use(fn) => void-
Returns ​

void

generateBundle()? ​
ts
optional generateBundle(this): void;

Emit the transpiled guest into the build.

Parameters ​
ParameterTypeDescription
thisEmitContextThe Rollup plugin context, for emitFile.
Returns ​

void


GuestStatus ​

The answer at GUEST_STATUS_PATH.

Example ​

ts
import type { GuestStatus } from 'gameable/vite';

const status: GuestStatus = { builtAt: 0, sourceAt: 1, stale: true };

Properties ​

builtAt ​
ts
builtAt: number;

The built guest's mtime in ms, or 0 when there is none.

sourceAt ​
ts
sourceAt: number;

The newest mtime among the sources it is built from.

stale ​
ts
stale: boolean;

No guest, or a source newer than it.

Type Aliases ​

DevMiddleware ​

ts
type DevMiddleware = (req, res, next) => void;

The slice of a connect middleware the plugin uses.

Parameters ​

ParameterType
req{ url?: string; }
req.url?string
res{ statusCode: number; end: void; setHeader: void; }
res.statusCodenumber
res.end
res.setHeader
next() => void

Returns ​

void


GameableMode ​

ts
type GameableMode = "direct" | "wasm";

Which sandbox the app should build.

Variables ​

ALWAYS_EXCLUDED ​

ts
const ALWAYS_EXCLUDED: readonly string[];

Packages whose emscripten glue must not be pre-bundled by esbuild.


GUEST_STATUS_PATH ​

ts
const GUEST_STATUS_PATH: "/__aos/guest-status.json" = '/__aos/guest-status.json';

Where the dev server answers whether the built guest is stale. The same path is GUEST_STATUS_PATH in gameable/net/solo, which asks it.

Example ​

ts
import { GUEST_STATUS_PATH } from 'gameable/vite';

console.log(GUEST_STATUS_PATH); // '/__aos/guest-status.json'

NEVER_INLINED ​

ts
const NEVER_INLINED: readonly string[];

Extensions never inlined as a data: URI.

A wasm module inlined as base64 cannot be streamed, and an engine asset inlined into the entry chunk is downloaded before the first frame instead of alongside it.


PACKAGE ​

ts
const PACKAGE: "gameable/vite";

Package identity marker for gameable/vite.

Example ​

ts
import { PACKAGE } from 'gameable/vite';

console.log(PACKAGE); // 'gameable/vite'

Functions ​

gameable() ​

ts
function gameable(options?): GameableVitePlugin;

The gameable Vite plugin.

Add it to plugins and the app resolves workspace packages from source, gets exactly one three, keeps the wasm runtimes out of the pre-bundle, serves .wasm correctly, and learns which sandbox to build through import.meta.env.GAMEABLE_MODE.

Parameters ​

ParameterTypeDescription
optionsGameableOptionsMode override, guest directory and the opt-outs.

Returns ​

GameableVitePlugin

A Vite plugin.

Example ​

ts
import { gameable } from 'gameable/vite';
import { defineConfig } from 'vite';

export default defineConfig({ plugins: [gameable()] });

guestFreshness() ​

ts
function guestFreshness(paths): GuestStatus;

Whether the built guest is older than what it is built from.

Parameters ​

ParameterTypeDescription
paths{ guestEntry: string; sources: readonly string[]; }The guest's entry and the sources.
paths.guestEntrystringThe transpiled guest's game.js (build/guest/game.js).
paths.sourcesreadonly string[]Files and directories it is built from.

Returns ​

GuestStatus

The newest mtimes, and stale when there is no guest or a source is newer.

Example ​

ts
import { guestFreshness, guestSources } from 'gameable/vite';

const status = guestFreshness({ guestEntry: 'build/guest/game.js', sources: guestSources('.') });
if (status.stale) console.warn('run npm run build:guest');

guestSources() ​

ts
function guestSources(root): string[];

What a game's guest is built from: its src/, its scripts/build-guest.mjs, and the SDK's sources when they are installed beside it (in this repository's workspace).

Parameters ​

ParameterTypeDescription
rootstringThe app root (Vite's root).

Returns ​

string[]

Absolute paths; missing ones count as never changed.

Example ​

ts
import { guestSources } from 'gameable/vite';

console.log(guestSources('/app')); // ['/app/src', '/app/scripts/build-guest.mjs', ...]

resolveGameableConfig() ​

ts
function resolveGameableConfig(options, env): GameableConfig;

Compute everything the plugin contributes, with no Vite involved.

Parameters ​

ParameterTypeDescription
optionsGameableOptionsThe plugin options.
envGameableEnvThe Vite command, process environment and app base.

Returns ​

GameableConfig

The configuration contribution.

Example ​

ts
import { resolveGameableConfig } from 'gameable/vite';

const config = resolveGameableConfig({}, { command: 'serve' });
console.log(config.conditions); // ['gameable-source']
console.log(config.define['import.meta.env.GAMEABLE_MODE']); // '"direct"'

resolveGameableMode() ​

ts
function resolveGameableMode(options, env): GameableMode;

Decide which sandbox the app is being built for.

Parameters ​

ParameterTypeDescription
optionsGameableOptionsThe plugin options.
envGameableEnvThe Vite command and process environment.

Returns ​

GameableMode

The mode.

Example ​

ts
import { resolveGameableMode } from 'gameable/vite';

console.log(resolveGameableMode({}, { command: 'serve' })); // 'direct'
console.log(resolveGameableMode({}, { command: 'build' })); // 'wasm'