@objectstack/runtime 4.2.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -5,6 +5,8 @@ import { z } from 'zod';
5
5
  import * as Contracts from '@objectstack/spec/contracts';
6
6
  import { ISeedLoaderService, IDataEngine, IMetadataService } from '@objectstack/spec/contracts';
7
7
  import { SeedLoaderRequest, SeedLoaderResult, ObjectDependencyGraph, Dataset, SeedLoaderConfigInput, ExpressionBody, ScriptBody, HookBody, Hook } from '@objectstack/spec/data';
8
+ import { MetricsRegistry, ErrorReporter } from '@objectstack/observability';
9
+ export { CapturedError, ErrorReporter, InMemoryErrorReporter, InMemoryMetricsRegistry, MetricSample, MetricsRegistry, NoopErrorReporter, NoopMetricsRegistry, RUNTIME_METRICS } from '@objectstack/observability';
8
10
  import { ExecutionContext } from '@objectstack/spec/kernel';
9
11
  import { MiddlewareConfig, MiddlewareType } from '@objectstack/spec/system';
10
12
  import { ProjectArtifact } from '@objectstack/spec/cloud';
@@ -490,142 +492,6 @@ declare function parseTraceparent(value: unknown): TraceContext | undefined;
490
492
  */
491
493
  declare function formatTraceparent(ctx: TraceContext): string;
492
494
 
493
- /**
494
- * Metrics registry contract.
495
- *
496
- * The runtime emits metrics via this interface so the host application
497
- * can plug in whatever metrics backend it wants (Prometheus via
498
- * `prom-client`, OTel via `@opentelemetry/api-metrics`, StatsD,
499
- * CloudWatch, etc.) without the framework taking a hard dep on any of
500
- * them.
501
- *
502
- * Naming follows Prometheus conventions:
503
- * - snake_case names
504
- * - unit suffix (`_ms`, `_seconds`, `_bytes`, `_total` for counters)
505
- *
506
- * Labels are arbitrary string maps; backends should map them to their
507
- * native label/tag concept. Keep cardinality low — never label by raw
508
- * url path or user id.
509
- *
510
- * All methods are fire-and-forget; implementations MUST NOT throw on
511
- * the hot path. Use {@link NoopMetricsRegistry} when metrics are
512
- * disabled.
513
- */
514
- interface MetricsRegistry {
515
- /** Monotonic counter. `value` defaults to 1. */
516
- counter(name: string, labels?: Record<string, string>, value?: number): void;
517
- /** Histogram / timing in arbitrary units (typically ms). */
518
- histogram(name: string, value: number, labels?: Record<string, string>): void;
519
- /** Point-in-time gauge. */
520
- gauge(name: string, value: number, labels?: Record<string, string>): void;
521
- }
522
- /**
523
- * No-op metrics registry — the default. Discards every observation.
524
- * Production deployments should swap this for a real registry; tests
525
- * can use {@link InMemoryMetricsRegistry} to assert emissions.
526
- */
527
- declare class NoopMetricsRegistry implements MetricsRegistry {
528
- counter(): void;
529
- histogram(): void;
530
- gauge(): void;
531
- }
532
- /** Recorded metric sample (in-memory registry). */
533
- interface MetricSample {
534
- name: string;
535
- kind: 'counter' | 'histogram' | 'gauge';
536
- value: number;
537
- labels: Record<string, string>;
538
- /** Wall-clock timestamp; useful for ordering assertions in tests. */
539
- at: number;
540
- }
541
- /**
542
- * In-memory registry used for tests and local inspection. Stores
543
- * every observation in insertion order; query via the helpers below
544
- * or read {@link samples} directly.
545
- *
546
- * Not intended for production — unbounded growth.
547
- */
548
- declare class InMemoryMetricsRegistry implements MetricsRegistry {
549
- readonly samples: MetricSample[];
550
- counter(name: string, labels?: Record<string, string>, value?: number): void;
551
- histogram(name: string, value: number, labels?: Record<string, string>): void;
552
- gauge(name: string, value: number, labels?: Record<string, string>): void;
553
- /**
554
- * Sum of all counter increments matching `name` (and optionally a
555
- * label subset). Useful in tests: `metrics.totalCounter('http_requests_total', { status: '500' })`.
556
- */
557
- totalCounter(name: string, labelMatch?: Record<string, string>): number;
558
- /**
559
- * All histogram observations matching `name` (and optionally a
560
- * label subset), as raw values.
561
- */
562
- histogramValues(name: string, labelMatch?: Record<string, string>): number[];
563
- /** Clear all recorded samples. */
564
- reset(): void;
565
- }
566
- /**
567
- * Canonical metric names emitted by the runtime. Hosts may rely on
568
- * these (e.g., to wire alerts) so they are listed here for reference
569
- * rather than being string literals scattered through call sites.
570
- */
571
- declare const RUNTIME_METRICS: {
572
- /** Counter, labels: method, route, status. */
573
- readonly httpRequestsTotal: "http_requests_total";
574
- /** Histogram (ms), labels: method, route. */
575
- readonly httpRequestDurationMs: "http_request_duration_ms";
576
- /** Counter, labels: method, route. Incremented when an in-flight handler throws (after the response is sent). */
577
- readonly httpRequestErrorsTotal: "http_request_errors_total";
578
- };
579
-
580
- /**
581
- * Error reporter contract.
582
- *
583
- * Production deployments wire this to Sentry, Datadog APM, Rollbar,
584
- * etc. The runtime calls {@link ErrorReporter.captureException} when a
585
- * route handler results in a 5xx response so the host's APM gets the
586
- * stack trace without each plugin/route needing to import the SDK.
587
- *
588
- * Implementations MUST NOT throw — error reporting failures should be
589
- * swallowed (or at most logged) so the original error reaches the
590
- * client unmolested.
591
- *
592
- * 4xx responses are intentionally NOT captured here. Client errors
593
- * (validation failures, auth, not-found) flood APM systems with noise
594
- * and obscure real bugs. If a deployment wants to track them, do it
595
- * via the metrics counter (`http_requests_total{status="4xx"}`),
596
- * not error reporting.
597
- */
598
- interface ErrorReporter {
599
- /**
600
- * Capture a thrown error with optional context. Context typically
601
- * includes `requestId`, `method`, `route`, `userId`, `orgId`.
602
- *
603
- * The reporter is responsible for redacting sensitive fields from
604
- * `context` (the runtime does not know what is sensitive in the
605
- * caller's deployment).
606
- */
607
- captureException(error: unknown, context?: Record<string, unknown>): void;
608
- }
609
- /** No-op reporter — the default. */
610
- declare class NoopErrorReporter implements ErrorReporter {
611
- captureException(): void;
612
- }
613
- /** Recorded report (in-memory reporter). */
614
- interface CapturedError {
615
- error: unknown;
616
- context: Record<string, unknown>;
617
- at: number;
618
- }
619
- /**
620
- * In-memory reporter used in tests to assert that error capture was
621
- * (or was not) invoked for a given request.
622
- */
623
- declare class InMemoryErrorReporter implements ErrorReporter {
624
- readonly captured: CapturedError[];
625
- captureException(error: unknown, context?: Record<string, unknown>): void;
626
- reset(): void;
627
- }
628
-
629
495
  interface DispatcherPluginConfig {
630
496
  /**
631
497
  * API path prefix for all endpoints.
@@ -2361,4 +2227,4 @@ declare function actionBodyRunnerFactory(runner: ScriptRunner, opts: FactoryOpti
2361
2227
  timeoutMs?: number;
2362
2228
  }) => ((actionCtx: any) => Promise<unknown>) | undefined;
2363
2229
 
2364
- export { AppPlugin, ArtifactApiClient, type ArtifactApiClientConfig, ArtifactEnvironmentRegistry, type ArtifactEnvironmentRegistryConfig, ArtifactKernelFactory, type ArtifactKernelFactoryConfig, AuthProxyPlugin, type BackfillPlatformSsoClientsOptions, type CapturedError, DEFAULT_RATE_LIMITS, type DefaultHostConfigOptions, type DefaultHostConfigResult, type DispatcherPluginConfig, DriverPlugin, type EnvironmentDriverRegistry, type ErrorReporter, FileArtifactApiClient, type FileArtifactApiClientConfig, HttpDispatcher, type HttpDispatcherResult, type HttpProtocolContext, HttpServer, InMemoryErrorReporter, InMemoryMetricsRegistry, KernelManager, type KernelManagerConfig, type LoadArtifactBundleOptions, type MetricSample, type MetricsRegistry, MiddlewareManager, NoopErrorReporter, NoopMetricsRegistry, type ObjectOSStackConfig, type ObjectOSStackResult, PLATFORM_SSO_PROVIDER_ID, type ProjectArtifactResponse, type ProjectKernelFactory, type ProjectRuntimeConfig, QuickJSScriptRunner, type QuickJSScriptRunnerOptions, RUNTIME_METRICS, type RateLimitBucketConfig, type RateLimitDecision, type RateLimitDefaults, type RateLimitStore, RateLimiter, type ResolvedHostname, Runtime, type RuntimeConfig, SYSTEM_PROJECT_ID, SandboxError, type ScriptContext, type ScriptOrigin, type ScriptResult, type ScriptRunOptions, type ScriptRunner, type SecurityHeadersOptions, SeedLoaderService, type SeedPlatformSsoClientOptions, type StandaloneStackConfig, type StandaloneStackResult, type SystemProjectPluginConfig, type TraceContext, UnimplementedScriptRunner, actionBodyRunnerFactory, backfillPlatformSsoClients, buildPlatformSsoRedirectUri, buildSecurityHeaders, collectBundleActions, collectBundleFunctions, collectBundleHooks, createDefaultHostConfig, createDispatcherPlugin, createObjectOSStack, createStandaloneStack, createSystemProjectPlugin, derivePlatformSsoClientId, derivePlatformSsoClientSecret, extractRequestId, formatTraceparent, generateRequestId, hookBodyRunnerFactory, isHttpUrl, loadArtifactBundle, mergeRuntimeModule, parseTraceparent, readArtifactSource, resolveDefaultArtifactPath, resolveRequestId, seedPlatformSsoClient };
2230
+ export { AppPlugin, ArtifactApiClient, type ArtifactApiClientConfig, ArtifactEnvironmentRegistry, type ArtifactEnvironmentRegistryConfig, ArtifactKernelFactory, type ArtifactKernelFactoryConfig, AuthProxyPlugin, type BackfillPlatformSsoClientsOptions, DEFAULT_RATE_LIMITS, type DefaultHostConfigOptions, type DefaultHostConfigResult, type DispatcherPluginConfig, DriverPlugin, type EnvironmentDriverRegistry, FileArtifactApiClient, type FileArtifactApiClientConfig, HttpDispatcher, type HttpDispatcherResult, type HttpProtocolContext, HttpServer, KernelManager, type KernelManagerConfig, type LoadArtifactBundleOptions, MiddlewareManager, type ObjectOSStackConfig, type ObjectOSStackResult, PLATFORM_SSO_PROVIDER_ID, type ProjectArtifactResponse, type ProjectKernelFactory, type ProjectRuntimeConfig, QuickJSScriptRunner, type QuickJSScriptRunnerOptions, type RateLimitBucketConfig, type RateLimitDecision, type RateLimitDefaults, type RateLimitStore, RateLimiter, type ResolvedHostname, Runtime, type RuntimeConfig, SYSTEM_PROJECT_ID, SandboxError, type ScriptContext, type ScriptOrigin, type ScriptResult, type ScriptRunOptions, type ScriptRunner, type SecurityHeadersOptions, SeedLoaderService, type SeedPlatformSsoClientOptions, type StandaloneStackConfig, type StandaloneStackResult, type SystemProjectPluginConfig, type TraceContext, UnimplementedScriptRunner, actionBodyRunnerFactory, backfillPlatformSsoClients, buildPlatformSsoRedirectUri, buildSecurityHeaders, collectBundleActions, collectBundleFunctions, collectBundleHooks, createDefaultHostConfig, createDispatcherPlugin, createObjectOSStack, createStandaloneStack, createSystemProjectPlugin, derivePlatformSsoClientId, derivePlatformSsoClientSecret, extractRequestId, formatTraceparent, generateRequestId, hookBodyRunnerFactory, isHttpUrl, loadArtifactBundle, mergeRuntimeModule, parseTraceparent, readArtifactSource, resolveDefaultArtifactPath, resolveRequestId, seedPlatformSsoClient };
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ import { z } from 'zod';
5
5
  import * as Contracts from '@objectstack/spec/contracts';
6
6
  import { ISeedLoaderService, IDataEngine, IMetadataService } from '@objectstack/spec/contracts';
7
7
  import { SeedLoaderRequest, SeedLoaderResult, ObjectDependencyGraph, Dataset, SeedLoaderConfigInput, ExpressionBody, ScriptBody, HookBody, Hook } from '@objectstack/spec/data';
8
+ import { MetricsRegistry, ErrorReporter } from '@objectstack/observability';
9
+ export { CapturedError, ErrorReporter, InMemoryErrorReporter, InMemoryMetricsRegistry, MetricSample, MetricsRegistry, NoopErrorReporter, NoopMetricsRegistry, RUNTIME_METRICS } from '@objectstack/observability';
8
10
  import { ExecutionContext } from '@objectstack/spec/kernel';
9
11
  import { MiddlewareConfig, MiddlewareType } from '@objectstack/spec/system';
10
12
  import { ProjectArtifact } from '@objectstack/spec/cloud';
@@ -490,142 +492,6 @@ declare function parseTraceparent(value: unknown): TraceContext | undefined;
490
492
  */
491
493
  declare function formatTraceparent(ctx: TraceContext): string;
492
494
 
493
- /**
494
- * Metrics registry contract.
495
- *
496
- * The runtime emits metrics via this interface so the host application
497
- * can plug in whatever metrics backend it wants (Prometheus via
498
- * `prom-client`, OTel via `@opentelemetry/api-metrics`, StatsD,
499
- * CloudWatch, etc.) without the framework taking a hard dep on any of
500
- * them.
501
- *
502
- * Naming follows Prometheus conventions:
503
- * - snake_case names
504
- * - unit suffix (`_ms`, `_seconds`, `_bytes`, `_total` for counters)
505
- *
506
- * Labels are arbitrary string maps; backends should map them to their
507
- * native label/tag concept. Keep cardinality low — never label by raw
508
- * url path or user id.
509
- *
510
- * All methods are fire-and-forget; implementations MUST NOT throw on
511
- * the hot path. Use {@link NoopMetricsRegistry} when metrics are
512
- * disabled.
513
- */
514
- interface MetricsRegistry {
515
- /** Monotonic counter. `value` defaults to 1. */
516
- counter(name: string, labels?: Record<string, string>, value?: number): void;
517
- /** Histogram / timing in arbitrary units (typically ms). */
518
- histogram(name: string, value: number, labels?: Record<string, string>): void;
519
- /** Point-in-time gauge. */
520
- gauge(name: string, value: number, labels?: Record<string, string>): void;
521
- }
522
- /**
523
- * No-op metrics registry — the default. Discards every observation.
524
- * Production deployments should swap this for a real registry; tests
525
- * can use {@link InMemoryMetricsRegistry} to assert emissions.
526
- */
527
- declare class NoopMetricsRegistry implements MetricsRegistry {
528
- counter(): void;
529
- histogram(): void;
530
- gauge(): void;
531
- }
532
- /** Recorded metric sample (in-memory registry). */
533
- interface MetricSample {
534
- name: string;
535
- kind: 'counter' | 'histogram' | 'gauge';
536
- value: number;
537
- labels: Record<string, string>;
538
- /** Wall-clock timestamp; useful for ordering assertions in tests. */
539
- at: number;
540
- }
541
- /**
542
- * In-memory registry used for tests and local inspection. Stores
543
- * every observation in insertion order; query via the helpers below
544
- * or read {@link samples} directly.
545
- *
546
- * Not intended for production — unbounded growth.
547
- */
548
- declare class InMemoryMetricsRegistry implements MetricsRegistry {
549
- readonly samples: MetricSample[];
550
- counter(name: string, labels?: Record<string, string>, value?: number): void;
551
- histogram(name: string, value: number, labels?: Record<string, string>): void;
552
- gauge(name: string, value: number, labels?: Record<string, string>): void;
553
- /**
554
- * Sum of all counter increments matching `name` (and optionally a
555
- * label subset). Useful in tests: `metrics.totalCounter('http_requests_total', { status: '500' })`.
556
- */
557
- totalCounter(name: string, labelMatch?: Record<string, string>): number;
558
- /**
559
- * All histogram observations matching `name` (and optionally a
560
- * label subset), as raw values.
561
- */
562
- histogramValues(name: string, labelMatch?: Record<string, string>): number[];
563
- /** Clear all recorded samples. */
564
- reset(): void;
565
- }
566
- /**
567
- * Canonical metric names emitted by the runtime. Hosts may rely on
568
- * these (e.g., to wire alerts) so they are listed here for reference
569
- * rather than being string literals scattered through call sites.
570
- */
571
- declare const RUNTIME_METRICS: {
572
- /** Counter, labels: method, route, status. */
573
- readonly httpRequestsTotal: "http_requests_total";
574
- /** Histogram (ms), labels: method, route. */
575
- readonly httpRequestDurationMs: "http_request_duration_ms";
576
- /** Counter, labels: method, route. Incremented when an in-flight handler throws (after the response is sent). */
577
- readonly httpRequestErrorsTotal: "http_request_errors_total";
578
- };
579
-
580
- /**
581
- * Error reporter contract.
582
- *
583
- * Production deployments wire this to Sentry, Datadog APM, Rollbar,
584
- * etc. The runtime calls {@link ErrorReporter.captureException} when a
585
- * route handler results in a 5xx response so the host's APM gets the
586
- * stack trace without each plugin/route needing to import the SDK.
587
- *
588
- * Implementations MUST NOT throw — error reporting failures should be
589
- * swallowed (or at most logged) so the original error reaches the
590
- * client unmolested.
591
- *
592
- * 4xx responses are intentionally NOT captured here. Client errors
593
- * (validation failures, auth, not-found) flood APM systems with noise
594
- * and obscure real bugs. If a deployment wants to track them, do it
595
- * via the metrics counter (`http_requests_total{status="4xx"}`),
596
- * not error reporting.
597
- */
598
- interface ErrorReporter {
599
- /**
600
- * Capture a thrown error with optional context. Context typically
601
- * includes `requestId`, `method`, `route`, `userId`, `orgId`.
602
- *
603
- * The reporter is responsible for redacting sensitive fields from
604
- * `context` (the runtime does not know what is sensitive in the
605
- * caller's deployment).
606
- */
607
- captureException(error: unknown, context?: Record<string, unknown>): void;
608
- }
609
- /** No-op reporter — the default. */
610
- declare class NoopErrorReporter implements ErrorReporter {
611
- captureException(): void;
612
- }
613
- /** Recorded report (in-memory reporter). */
614
- interface CapturedError {
615
- error: unknown;
616
- context: Record<string, unknown>;
617
- at: number;
618
- }
619
- /**
620
- * In-memory reporter used in tests to assert that error capture was
621
- * (or was not) invoked for a given request.
622
- */
623
- declare class InMemoryErrorReporter implements ErrorReporter {
624
- readonly captured: CapturedError[];
625
- captureException(error: unknown, context?: Record<string, unknown>): void;
626
- reset(): void;
627
- }
628
-
629
495
  interface DispatcherPluginConfig {
630
496
  /**
631
497
  * API path prefix for all endpoints.
@@ -2361,4 +2227,4 @@ declare function actionBodyRunnerFactory(runner: ScriptRunner, opts: FactoryOpti
2361
2227
  timeoutMs?: number;
2362
2228
  }) => ((actionCtx: any) => Promise<unknown>) | undefined;
2363
2229
 
2364
- export { AppPlugin, ArtifactApiClient, type ArtifactApiClientConfig, ArtifactEnvironmentRegistry, type ArtifactEnvironmentRegistryConfig, ArtifactKernelFactory, type ArtifactKernelFactoryConfig, AuthProxyPlugin, type BackfillPlatformSsoClientsOptions, type CapturedError, DEFAULT_RATE_LIMITS, type DefaultHostConfigOptions, type DefaultHostConfigResult, type DispatcherPluginConfig, DriverPlugin, type EnvironmentDriverRegistry, type ErrorReporter, FileArtifactApiClient, type FileArtifactApiClientConfig, HttpDispatcher, type HttpDispatcherResult, type HttpProtocolContext, HttpServer, InMemoryErrorReporter, InMemoryMetricsRegistry, KernelManager, type KernelManagerConfig, type LoadArtifactBundleOptions, type MetricSample, type MetricsRegistry, MiddlewareManager, NoopErrorReporter, NoopMetricsRegistry, type ObjectOSStackConfig, type ObjectOSStackResult, PLATFORM_SSO_PROVIDER_ID, type ProjectArtifactResponse, type ProjectKernelFactory, type ProjectRuntimeConfig, QuickJSScriptRunner, type QuickJSScriptRunnerOptions, RUNTIME_METRICS, type RateLimitBucketConfig, type RateLimitDecision, type RateLimitDefaults, type RateLimitStore, RateLimiter, type ResolvedHostname, Runtime, type RuntimeConfig, SYSTEM_PROJECT_ID, SandboxError, type ScriptContext, type ScriptOrigin, type ScriptResult, type ScriptRunOptions, type ScriptRunner, type SecurityHeadersOptions, SeedLoaderService, type SeedPlatformSsoClientOptions, type StandaloneStackConfig, type StandaloneStackResult, type SystemProjectPluginConfig, type TraceContext, UnimplementedScriptRunner, actionBodyRunnerFactory, backfillPlatformSsoClients, buildPlatformSsoRedirectUri, buildSecurityHeaders, collectBundleActions, collectBundleFunctions, collectBundleHooks, createDefaultHostConfig, createDispatcherPlugin, createObjectOSStack, createStandaloneStack, createSystemProjectPlugin, derivePlatformSsoClientId, derivePlatformSsoClientSecret, extractRequestId, formatTraceparent, generateRequestId, hookBodyRunnerFactory, isHttpUrl, loadArtifactBundle, mergeRuntimeModule, parseTraceparent, readArtifactSource, resolveDefaultArtifactPath, resolveRequestId, seedPlatformSsoClient };
2230
+ export { AppPlugin, ArtifactApiClient, type ArtifactApiClientConfig, ArtifactEnvironmentRegistry, type ArtifactEnvironmentRegistryConfig, ArtifactKernelFactory, type ArtifactKernelFactoryConfig, AuthProxyPlugin, type BackfillPlatformSsoClientsOptions, DEFAULT_RATE_LIMITS, type DefaultHostConfigOptions, type DefaultHostConfigResult, type DispatcherPluginConfig, DriverPlugin, type EnvironmentDriverRegistry, FileArtifactApiClient, type FileArtifactApiClientConfig, HttpDispatcher, type HttpDispatcherResult, type HttpProtocolContext, HttpServer, KernelManager, type KernelManagerConfig, type LoadArtifactBundleOptions, MiddlewareManager, type ObjectOSStackConfig, type ObjectOSStackResult, PLATFORM_SSO_PROVIDER_ID, type ProjectArtifactResponse, type ProjectKernelFactory, type ProjectRuntimeConfig, QuickJSScriptRunner, type QuickJSScriptRunnerOptions, type RateLimitBucketConfig, type RateLimitDecision, type RateLimitDefaults, type RateLimitStore, RateLimiter, type ResolvedHostname, Runtime, type RuntimeConfig, SYSTEM_PROJECT_ID, SandboxError, type ScriptContext, type ScriptOrigin, type ScriptResult, type ScriptRunOptions, type ScriptRunner, type SecurityHeadersOptions, SeedLoaderService, type SeedPlatformSsoClientOptions, type StandaloneStackConfig, type StandaloneStackResult, type SystemProjectPluginConfig, type TraceContext, UnimplementedScriptRunner, actionBodyRunnerFactory, backfillPlatformSsoClients, buildPlatformSsoRedirectUri, buildSecurityHeaders, collectBundleActions, collectBundleFunctions, collectBundleHooks, createDefaultHostConfig, createDispatcherPlugin, createObjectOSStack, createStandaloneStack, createSystemProjectPlugin, derivePlatformSsoClientId, derivePlatformSsoClientSecret, extractRequestId, formatTraceparent, generateRequestId, hookBodyRunnerFactory, isHttpUrl, loadArtifactBundle, mergeRuntimeModule, parseTraceparent, readArtifactSource, resolveDefaultArtifactPath, resolveRequestId, seedPlatformSsoClient };