npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@simplysm/service-server

v13.0.69

Published

심플리즘 패키지 - 서비스 모듈 (server)

Readme

@simplysm/service-server

A Fastify-based HTTP/WebSocket server package. Provides server features needed for full-stack applications, including RPC-style service invocation, JWT authentication, file upload, static file serving, and real-time events.

Used together with @simplysm/service-client to configure WebSocket/HTTP communication between client and server.

Installation

npm install @simplysm/service-server
# or
pnpm add @simplysm/service-server

Main Modules

Core Functions and Classes

  • createServiceServer - Factory function for creating a ServiceServer instance
  • ServiceServer - Main server class. Creates a Fastify instance and configures routes/plugins
  • defineService - Defines a service with a name and factory function
  • ServiceContext - Context object passed to service factory functions
  • createServiceContext - Factory function that creates a ServiceContext (exported for advanced use)
  • runServiceMethod - Dispatches a service method call with auth checks and execution
  • ServiceDefinition - Type describing a registered service (name + factory + authPermissions)
  • ServiceMethods - Type utility that extracts method signatures from a ServiceDefinition

Authentication

  • auth - Wrapper that sets authentication requirements at service or method level
  • getServiceAuthPermissions - Reads auth permissions from an auth()-wrapped function
  • signJwt - Generate a JWT token (HS256, 12-hour expiration)
  • verifyJwt - Verify and decode a JWT token
  • decodeJwt - Decode a JWT token without verification (synchronous)
  • AuthTokenPayload - JWT payload interface (includes roles, data)

Transport Layer - WebSocket

  • WebSocketHandler - Interface for managing multiple WebSocket connections, routing messages, and broadcasting events
  • createWebSocketHandler - Factory function that creates a WebSocketHandler instance
  • ServiceSocket - Interface wrapping a single WebSocket connection. Manages ping/pong, protocol encoding/decoding, event listener management
  • createServiceSocket - Factory function that creates a ServiceSocket instance

Transport Layer - HTTP

  • handleHttpRequest - Handles service method calls via HTTP at /api/:service/:method
  • handleUpload - Handles multipart file upload at /upload (auth required)
  • handleStaticFile - Serves static files from rootPath/www/. Prevents path traversal and blocks hidden files

Protocol

  • ProtocolWrapper - Interface for message encoding/decoding. Messages over 30KB are processed in worker threads
  • createProtocolWrapper - Factory function that creates a ProtocolWrapper instance

Built-in Services

  • OrmService - DB connection/transaction/query execution (WebSocket only, auth required)
  • OrmServiceType - Type alias for OrmService method signatures (for client-side type sharing)
  • AutoUpdateService - App auto-update (provides latest version query and download path)
  • AutoUpdateServiceType - Type alias for AutoUpdateService method signatures (for client-side type sharing)

Utilities

  • getConfig - JSON config file loading with caching and real-time file watching

Legacy

  • handleV1Connection - V1 protocol client compatibility handling (supports auto-update only)

Usage

Basic Server Configuration

import { createServiceServer } from "@simplysm/service-server";

const server = createServiceServer({
  port: 8080,
  rootPath: "/app/data",
  services: [MyService],
});

// Start server
await server.listen();

// Receive events
server.on("ready", () => {
  console.log("Server ready");
});

server.on("close", () => {
  console.log("Server closed");
});

// Close server
await server.close();

Server Options

See ServiceServerOptions for detailed configuration options including SSL, authentication, and directory structure.

Custom Services

Services are defined using the defineService function. Service methods are called via RPC from the client.

import { defineService } from "@simplysm/service-server";

export const MyService = defineService("My", (ctx) => ({
  hello: async (name: string): Promise<string> => {
    return `Hello, ${name}!`;
  },

  getServerTime: async (): Promise<Date> => {
    return new Date();
  },
}));

// Export type for client-side type sharing
export type MyServiceMethods = import("@simplysm/service-server").ServiceMethods<typeof MyService>;

ServiceContext

The ctx parameter provides access to server resources:

  • ctx.server - ServiceServer instance
  • ctx.socket - ServiceSocket instance (WebSocket only, undefined for HTTP)
  • ctx.http - HTTP request/reply objects (HTTP only, undefined for WebSocket)
  • ctx.authInfo - Authentication info (set via JWT token)
  • ctx.clientName - Client identifier
  • ctx.clientPath - Resolved per-client directory path (rootPath/www/{clientName})
  • ctx.getConfig(section) - Get server config by section name

Authentication

Use the auth() wrapper to set authentication requirements at service or method level:

import { defineService, auth } from "@simplysm/service-server";

interface UserAuthInfo {
  userId: number;
  role: string;
}

// Service-level auth: all methods require authentication
export const UserService = defineService("User", auth((ctx) => ({
  getProfile: async (): Promise<unknown> => {
    const userId = (ctx.authInfo as UserAuthInfo)?.userId;
    // ...
  },

  deleteUser: auth(["admin"], async (targetId: number): Promise<void> => {
    // Only users with admin role can call
  }),
})));

export type UserServiceMethods = import("@simplysm/service-server").ServiceMethods<typeof UserService>;

Auth Patterns

Method-level auth only:

export const MyService = defineService("My", (ctx) => ({
  publicMethod: async (): Promise<void> => {
    // No auth required
  },

  protectedMethod: auth(async (): Promise<void> => {
    // Auth required
  }),

  adminMethod: auth(["admin"], async (): Promise<void> => {
    // Auth + admin role required
  }),
}));

Service-level auth with method override:

// All methods require authentication by default
export const SecureService = defineService("Secure", auth((ctx) => ({
  normalMethod: async (): Promise<void> => {
    // Auth required (inherited from service level)
  },

  adminMethod: auth(["admin"], async (): Promise<void> => {
    // Auth + admin role required
  }),
})));

See Authentication for JWT token management and permission handling.

HTTP/WebSocket Communication

Service methods can be called via HTTP or WebSocket:

GET /api/My/hello?json=["World"]
POST /api/My/hello

See HTTP API Call and ServiceSocket for transport layer details.

File Upload

Upload files via multipart request to the /upload endpoint:

const formData = new FormData();
formData.append("file", file);

const response = await fetch("/upload", {
  method: "POST",
  headers: { Authorization: `Bearer ${token}` },
  body: formData,
});

See File Upload for more details.

Event Publishing

Publish real-time events to connected WebSocket clients:

import { defineEvent } from "@simplysm/service-common";

export const OrderUpdatedEvent = defineEvent<
  { orderId: number },
  { status: string }
>("OrderUpdatedEvent");

await server.emitEvent(
  OrderUpdatedEvent,
  (info) => info.orderId === 123,
  { status: "completed" },
);

See Real-time Event Publishing for more details.

Built-in Services

The package provides several built-in services:

Register them like any other service:

import { createServiceServer, OrmService } from "@simplysm/service-server";

const server = createServiceServer({
  port: 8080,
  rootPath: "/app/data",
  auth: { jwtSecret: "secret" },
  services: [OrmService],
});

Security

  • Helmet: @fastify/helmet plugin automatically sets security headers like CSP, HSTS
  • CORS: @fastify/cors plugin configures CORS
  • Path Traversal Prevention: Static file handler and client name validation block .., /, \ characters
  • Hidden File Blocking: Files starting with . return a 403 response
  • Directory Trailing Slash Redirect: Directory requests without a trailing slash are redirected to the same path with a trailing slash (standard web server behavior)
  • Graceful Shutdown: Detects SIGINT/SIGTERM signals to safely close WebSocket connections and server (10-second timeout)

See Security for more details.

License

Apache-2.0