npm install @nightnetwork/enigmanpm install @mercuryworkshop/bare-mux @mercuryworkshop/epoxy-transport<!DOCTYPE html>
<html>
<head>
<title>Enigma Demo</title>
</head>
<body>
<script src="/baremux/bare-mux.js"></script>
<script type="module" src="app.js"></script>
</body>
</html>const connection = new window.BareMux.BareMuxConnection('/baremux/worker.js');
await connection.setTransport('/enigma/index.mjs', [{
base: '/epoxy/index.mjs',
wisp: 'wss://wisp.example.com/',
modules: []
}]);await connection.setTransport('/enigma/index.mjs', [{
base: '/epoxy/index.mjs',
wisp: 'wss://wisp.example.com/',
modules: ['/modules/logger.mjs']
}]);await connection.setTransport('/enigma/index.mjs', [{
base: '/epoxy/index.mjs',
wisp: 'wss://wisp.example.com/',
modules: [
{
path: '/modules/logger.mjs',
options: { verbose: true }
}
]
}]);await connection.setTransport('/enigma/index.mjs', [{
base: '/epoxy/index.mjs',
wisp: 'wss://wisp.example.com/',
modules: [
'/modules/auth.mjs',
{ path: '/modules/logger.mjs', options: { verbose: true } },
'/modules/cache.mjs'
]
}]);Create modules/logger.mjs:
export const MODULE_ID = 'com.example.logger';
export function createLoggerModule(options = {}) {
const verbose = options.verbose ?? false;
return {
id: MODULE_ID,
name: 'Request Logger',
version: '1.0.0',
priority: 20,
capabilities: {
requestInterception: true,
responseInterception: true
},
hooks: {
onBeforeRequest: async (ctx, next) => {
console.log('→', ctx.method, ctx.remote.href);
return await next();
},
onAfterResponse: async (ctx, next) => {
const response = await next();
console.log('←', response.status, ctx.remote.href);
return response;
}
}
};
}
export default createLoggerModule;export const MODULE_ID = 'com.company.module';
export function createModule(options = {}) {
return {
id: MODULE_ID,
name: 'Module Name',
version: '1.0.0',
priority: 50,
capabilities: {
requestInterception: boolean,
responseInterception: boolean,
websocketInterception: boolean,
protocolModification: boolean
},
hooks: {
onModuleInit: async () => {},
onTransportInit: async (innerTransport) => {},
onBeforeRequest: async (ctx, next) => await next(),
onAfterResponse: async (ctx, next) => await next(),
onWebSocketConnect: async (ctx, handlers, next) => next(),
onWebSocketMessage: (data, direction, url) => data,
provideMeta: () => ({})
}
};
}
export default createModule;Called when module loads.
onModuleInit: async () => {
console.log('Module initialized');
}Called when base transport is ready.
onTransportInit: async (innerTransport) => {
console.log('Transport ready');
}Intercept requests. Context has:
ctx.remote- URL objectctx.method- HTTP methodctx.body- Request bodyctx.headers- BareHeadersctx.signal- AbortSignal
onBeforeRequest: async (ctx, next) => {
ctx.headers.set('X-Custom', 'value');
return await next();
}Intercept responses. Context has:
ctx.remote- URL objectctx.body- ReadableStream | ArrayBuffer | Blob | stringctx.headers- BareHeadersctx.status- Status codectx.statusText- Status text
onAfterResponse: async (ctx, next) => {
const response = await next();
console.log('Status:', response.status);
return response;
}Intercept WebSocket connections. Context has:
ctx.url- URL objectctx.protocols- string[]ctx.requestHeaders- BareHeaders
onWebSocketConnect: async (ctx, handlers, next) => {
console.log('WS connecting:', ctx.url.href);
return next();
}Transform WebSocket messages.
onWebSocketMessage: (data, direction, url) => {
console.log(`WS ${direction}:`, data);
return data;
}Expose module metadata.
provideMeta: () => ({
requestCount: 42
})| Priority | Use Case |
|---|---|
| 90-100 | Protocol modification |
| 80-89 | Security |
| 50-79 | Middleware |
| 40-49 | Caching |
| 10-39 | Logging |
<!DOCTYPE html>
<html>
<head>
<title>Enigma Demo</title>
</head>
<body>
<button id="test">Test</button>
<script src="/baremux/bare-mux.js"></script>
<script type="module">
const connection = new window.BareMux.BareMuxConnection('/baremux/worker.js');
await connection.setTransport('/enigma/index.mjs', [{
base: '/epoxy/index.mjs',
wisp: 'wss://wisp.example.com/',
modules: ['/modules/logger.mjs']
}]);
console.log('Ready!');
document.getElementById('test').onclick = async () => {
const res = await fetch('https://example.com');
console.log('Response:', res.status);
};
</script>
</body>
</html>