New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@servlyadmin/runtime-core

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@servlyadmin/runtime-core

Framework-agnostic core renderer for Servly components

npmnpm
Version
0.1.32
Version published
Weekly downloads
10
-58.33%
Maintainers
1
Weekly downloads
 
Created
Source

@servlyadmin/runtime-core

Framework-agnostic core renderer for Servly components. This package provides the foundation for rendering Servly components in any JavaScript environment.

Installation

npm install @servlyadmin/runtime-core
# or
yarn add @servlyadmin/runtime-core
# or
pnpm add @servlyadmin/runtime-core

Quick Start

import { render, fetchComponent } from '@servlyadmin/runtime-core';

// Fetch a component from the registry
const { data } = await fetchComponent('my-component', { version: 'latest' });

// Render to a container
const result = render({
  container: document.getElementById('app'),
  elements: data.layout,
  context: {
    props: { title: 'Hello World' },
    state: {},
    context: {},
  },
});

// Update props
result.update({
  props: { title: 'Updated Title' },
  state: {},
  context: {},
});

// Cleanup
result.destroy();

Core Concepts

Layout Elements

Components are defined as a tree of layout elements:

interface LayoutElement {
  i: string;           // Unique identifier
  type: string;        // HTML tag or component type
  configuration?: {    // Element configuration
    className?: string;
    style?: Record<string, any>;
    textContent?: string;
    // ... other attributes
  };
  children?: LayoutElement[];  // Nested elements
}

Binding Context

Data is passed to components through a binding context:

interface BindingContext {
  props: Record<string, any>;   // Component props
  state: Record<string, any>;   // Component state
  context: Record<string, any>; // Additional context
}

Template Bindings

Use {{path}} syntax to bind data:

const elements = [
  {
    i: 'greeting',
    type: 'h1',
    configuration: {
      textContent: 'Hello, {{props.name}}!',
      className: '{{props.className}}',
    },
  },
];

API Reference

render(options)

Renders elements to a container.

const result = render({
  container: HTMLElement,
  elements: LayoutElement[],
  context: BindingContext,
  eventHandlers?: Record<string, Record<string, (e: Event) => void>>,
});

// Returns
interface RenderResult {
  update(context: BindingContext): void;
  destroy(): void;
  getElement(id: string): HTMLElement | null;
}

fetchComponent(id, options?)

Fetches a component from the registry.

const { data, fromCache } = await fetchComponent('component-id', {
  version: 'latest',        // Version specifier
  cacheStrategy: 'memory',  // 'memory' | 'localStorage' | 'none'
  forceRefresh: false,      // Bypass cache
  timeout: 30000,           // Request timeout in ms
  retryConfig: {
    maxRetries: 3,
    retryDelay: 1000,
  },
});

StateManager

Manages component state with subscriptions.

import { StateManager } from '@servlyadmin/runtime-core';

const stateManager = new StateManager({ count: 0 });

// Get/set state
stateManager.setState({ count: 1 });
stateManager.getValue('count'); // 1
stateManager.setValue('user.name', 'John');

// Subscribe to changes
const unsubscribe = stateManager.subscribe((state) => {
  console.log('State changed:', state);
});

// Subscribe to specific path
stateManager.subscribeToPath('count', (value) => {
  console.log('Count changed:', value);
});

// Batch updates
stateManager.batch(() => {
  stateManager.setValue('a', 1);
  stateManager.setValue('b', 2);
}); // Only one notification

EventSystem

Handles events with plugin-based actions.

import { EventSystem } from '@servlyadmin/runtime-core';

const eventSystem = new EventSystem();

// Register custom plugin
eventSystem.registerPlugin('my-action', async (config, context) => {
  console.log('Action executed with:', config);
});

// Create event handler
const handler = eventSystem.createHandler([
  { key: 'prevent-default', config: {} },
  { key: 'set-state', config: { path: 'clicked', value: true } },
  { key: 'my-action', config: { message: 'Button clicked!' } },
]);

// Use with element
button.addEventListener('click', (e) => {
  handler(e, 'button-id', bindingContext);
});

Built-in Plugins

  • console-log - Log messages to console
  • set-state - Update state values
  • delay - Add delay between actions
  • prevent-default - Call event.preventDefault()
  • stop-propagation - Call event.stopPropagation()

Cache

Component caching with multiple strategies.

import { ComponentCache } from '@servlyadmin/runtime-core';

const cache = new ComponentCache({
  maxSize: 100,
  strategy: 'memory', // 'memory' | 'localStorage' | 'none'
});

// Set with TTL
cache.set('key', data, { ttl: 60000 }); // 1 minute

// Component-specific methods
cache.setComponent('comp-id', '1.0.0', componentData);
cache.getComponent('comp-id', 'latest');
cache.invalidateComponent('comp-id');

// Statistics
const stats = cache.getStats();
console.log(`Hit rate: ${stats.hitRate * 100}%`);

Bindings

Template resolution utilities.

import { resolveTemplate, resolveBindings, isTemplate } from '@servlyadmin/runtime-core';

const context = {
  props: { name: 'World', count: 42 },
  state: {},
  context: {},
};

// Resolve single template
resolveTemplate('Hello, {{props.name}}!', context); // "Hello, World!"

// Check if string is a template
isTemplate('{{props.name}}'); // true
isTemplate('static text');    // false

// Resolve all bindings in an object
resolveBindings({
  title: '{{props.name}}',
  subtitle: 'Count: {{props.count}}',
}, context);
// { title: 'World', subtitle: 'Count: 42' }

Slots

Components can define slots for content injection:

const elements = [
  {
    i: 'card',
    type: 'div',
    configuration: { className: 'card' },
    children: [
      {
        i: 'header-slot',
        type: 'div',
        configuration: {
          'data-slot': 'header', // Slot placeholder
        },
      },
      {
        i: 'content-slot',
        type: 'div',
        configuration: {
          'data-slot': 'default',
        },
      },
    ],
  },
];

Framework wrappers handle slot content injection automatically.

TypeScript Support

Full TypeScript support with exported types:

import type {
  LayoutElement,
  BindingContext,
  RenderResult,
  ComponentData,
  CacheStrategy,
  RetryConfig,
} from '@servlyadmin/runtime-core';

Browser Support

  • Chrome 80+
  • Firefox 75+
  • Safari 13+
  • Edge 80+

License

MIT

Keywords

servly

FAQs

Package last updated on 22 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts