@almadar/runtime 6.9.2 → 6.9.3

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.
@@ -1,7 +1,7 @@
1
1
  import * as _almadar_core from '@almadar/core';
2
2
  import { EventPayload, EntityRow, OrbitalSchema, Orbital, Trait, PatternConfig, ResolvedPatternProps, SExpr, BusEventSource, OrbitalDefinition, Entity, TraitConfig, TraitTick } from '@almadar/core';
3
3
  import { Router } from 'express';
4
- import { I as IEventBus, g as RuntimeEvent, e as EventListener, U as Unsubscribe, T as TraitDefinition, R as RuntimeConfig, i as TransitionObserver, C as ConfigContext, h as TraitState, j as TransitionResult, d as EvaluationContextExtensions, b as EffectHandlers } from './types-CjvQG_33.js';
4
+ import { I as IEventBus, g as RuntimeEvent, f as EventListener, U as Unsubscribe, T as TraitDefinition, R as RuntimeConfig, i as TransitionObserver, C as ConfigContext, h as TraitState, j as TransitionResult, E as EvaluationContextExtensions, a as EffectHandlers } from './types-cuy5gd29.js';
5
5
  import { P as PersistenceAdapter } from './PersistenceAdapter-B6dQCbbU.js';
6
6
 
7
7
  /**
@@ -1158,4 +1158,4 @@ declare class OrbitalServerRuntime {
1158
1158
  */
1159
1159
  declare function createOrbitalServerRuntime(config?: OrbitalServerRuntimeConfig): OrbitalServerRuntime;
1160
1160
 
1161
- export { getNamespacedEvent as A, isBrowser as B, type ClientEffectTuple as C, isElectron as D, type EffectResult as E, isNamespacedEvent as F, isNode as G, normalizeEventKey as H, type ImportChainLike as I, parseNamespacedEvent as J, preprocessSchema as K, type LoadResult as L, processEvent as M, type OrbitalEventRequest as O, type PreprocessOptions as P, type RegisteredOrbital as R, type SchemaLoader as S, type UnifiedLoaderOptions as U, type ClientNavigateTuple as a, type ClientNotifyTuple as b, type ClientRenderUITuple as c, type EntitySharingMap as d, EventBus as e, type EventNamespaceMap as f, type LoadedOrbital as g, type LoadedSchema as h, type LoaderConfig as i, type OrbitalEventResponse as j, OrbitalServerRuntime as k, type OrbitalServerRuntimeConfig as l, type PreprocessResult as m, type PreprocessedSchema as n, type ProcessEventOptions as o, type RuntimeOrbital as p, type RuntimeOrbitalSchema as q, type RuntimeTrait as r, type RuntimeTraitTick as s, StateMachineManager as t, collectDeclaredConfigDefaults as u, createInitialTraitState as v, createOrbitalServerRuntime as w, findInitialState as x, findTransition as y, getIsolatedCollectionName as z };
1161
+ export { processEvent as A, type ClientNavigateTuple as B, type ClientEffectTuple as C, type ClientNotifyTuple as D, type EntitySharingMap as E, type ClientRenderUITuple as F, type EffectResult as G, type LoaderConfig as H, type ImportChainLike as I, OrbitalServerRuntime as J, type RuntimeTraitTick as K, type LoadResult as L, createOrbitalServerRuntime as M, type OrbitalEventRequest as O, type PreprocessOptions as P, type RegisteredOrbital as R, type SchemaLoader as S, type UnifiedLoaderOptions as U, type LoadedSchema as a, type LoadedOrbital as b, EventBus as c, type EventNamespaceMap as d, type OrbitalEventResponse as e, type OrbitalServerRuntimeConfig as f, type PreprocessResult as g, type PreprocessedSchema as h, type ProcessEventOptions as i, type RuntimeOrbital as j, type RuntimeOrbitalSchema as k, type RuntimeTrait as l, StateMachineManager as m, collectDeclaredConfigDefaults as n, createInitialTraitState as o, findInitialState as p, findTransition as q, getIsolatedCollectionName as r, getNamespacedEvent as s, isBrowser as t, isElectron as u, isNamespacedEvent as v, isNode as w, normalizeEventKey as x, parseNamespacedEvent as y, preprocessSchema as z };
@@ -1,5 +1,5 @@
1
1
  import '@almadar/core';
2
2
  import 'express';
3
- export { C as ClientEffectTuple, a as ClientNavigateTuple, b as ClientNotifyTuple, c as ClientRenderUITuple, E as EffectResult, i as LoaderConfig, O as OrbitalEventRequest, j as OrbitalEventResponse, k as OrbitalServerRuntime, l as OrbitalServerRuntimeConfig, R as RegisteredOrbital, p as RuntimeOrbital, q as RuntimeOrbitalSchema, r as RuntimeTrait, s as RuntimeTraitTick, u as collectDeclaredConfigDefaults, w as createOrbitalServerRuntime } from './OrbitalServerRuntime-CzUrdroI.js';
4
- import './types-CjvQG_33.js';
3
+ export { C as ClientEffectTuple, B as ClientNavigateTuple, D as ClientNotifyTuple, F as ClientRenderUITuple, G as EffectResult, H as LoaderConfig, O as OrbitalEventRequest, e as OrbitalEventResponse, J as OrbitalServerRuntime, f as OrbitalServerRuntimeConfig, R as RegisteredOrbital, j as RuntimeOrbital, k as RuntimeOrbitalSchema, l as RuntimeTrait, K as RuntimeTraitTick, n as collectDeclaredConfigDefaults, M as createOrbitalServerRuntime } from './OrbitalServerRuntime-CvWqVb68.js';
4
+ import './types-cuy5gd29.js';
5
5
  export { I as InMemoryPersistence, P as PersistenceAdapter } from './PersistenceAdapter-B6dQCbbU.js';
@@ -1,4 +1,4 @@
1
- import { I as IEventBus } from './types-CjvQG_33.js';
1
+ import { I as IEventBus } from './types-cuy5gd29.js';
2
2
  import { EventPayload } from '@almadar/core';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { b as EffectHandlers } from './types-CjvQG_33.js';
1
+ import { a as EffectHandlers } from './types-cuy5gd29.js';
2
2
  import { EventPayload } from '@almadar/core';
3
3
 
4
4
  /**
@@ -1,7 +1,7 @@
1
1
  import './chunk-PZ5AY32C.js';
2
2
  import * as fs from 'fs';
3
3
  import * as net from 'net';
4
- import { execSync } from 'child_process';
4
+ import { execFileSync } from 'child_process';
5
5
  import { createLogger } from '@almadar/logger';
6
6
 
7
7
  var log = createLogger("almadar:runtime:os-handlers");
@@ -120,13 +120,17 @@ function createOsHandlers(ctx) {
120
120
  },
121
121
  osWatchProcess: (name, subcommand, emit) => {
122
122
  const searchTerm = subcommand ? `${name} ${subcommand}` : name;
123
+ if (!/^[\w .\-/:@]+$/.test(searchTerm)) {
124
+ log.warn("watch-process-invalid-name", { searchTerm });
125
+ return;
126
+ }
123
127
  let wasRunning = false;
124
128
  const startEvent = resolveOnMessage(emit, "OS_PROCESS_STARTED");
125
129
  const exitEvent = resolveOnMessage(emit, "OS_PROCESS_EXITED");
126
130
  const interval = setInterval(() => {
127
131
  let isRunning = false;
128
132
  try {
129
- const result = execSync(`pgrep -f "${searchTerm}" 2>/dev/null`, {
133
+ const result = execFileSync("pgrep", ["-f", searchTerm], {
130
134
  encoding: "utf-8",
131
135
  stdio: ["pipe", "pipe", "pipe"]
132
136
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/createOsHandlers.ts"],"names":[],"mappings":"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","file":"createOsHandlers.js","sourcesContent":["/**\n * OS Trigger Handlers — Server-Side Only\n *\n * Provides Node.js implementations for all 8 os/* operators.\n * Used by OrbitalServerRuntime (interpreted path).\n *\n * NOT exported from the main index.ts because it imports Node.js-only modules.\n * Import directly: import { createOsHandlers } from '@almadar/runtime/createOsHandlers';\n *\n * @packageDocumentation\n */\n\nimport * as fs from \"fs\";\nimport * as net from \"net\";\nimport { execSync } from \"child_process\";\nimport { createLogger } from '@almadar/logger';\nimport type { EventPayload, OsEmitConfig } from './types.js';\nimport type { EffectHandlers } from \"./types.js\";\n\nconst log = createLogger('almadar:runtime:os-handlers');\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface OsHandlerContext {\n /** Emit an event on the EventBus */\n emitEvent: (type: string, payload: EventPayload) => void;\n /** Working directory for file watching (defaults to process.cwd()) */\n cwd?: string;\n}\n\nexport interface OsHandlerResult {\n handlers: Partial<EffectHandlers>;\n cleanup: () => void;\n}\n\n// ============================================================================\n// Glob Matching (minimal, no external dependency)\n// ============================================================================\n\nfunction globToRegex(glob: string): RegExp {\n let regex = \"\";\n let i = 0;\n while (i < glob.length) {\n const c = glob[i];\n if (c === \"*\") {\n if (glob[i + 1] === \"*\") {\n // ** matches any path segment\n regex += \".*\";\n i += 2;\n if (glob[i] === \"/\") i++; // skip trailing slash\n continue;\n }\n // * matches anything except /\n regex += \"[^/]*\";\n } else if (c === \"?\") {\n regex += \"[^/]\";\n } else if (c === \".\") {\n regex += \"\\\\.\";\n } else if (c === \"/\" || c === \"-\" || c === \"_\") {\n regex += c;\n } else if (/[{}()[\\]^$+|\\\\]/.test(c)) {\n regex += \"\\\\\" + c;\n } else {\n regex += c;\n }\n i++;\n }\n return new RegExp(\"^\" + regex + \"$\");\n}\n\n// ============================================================================\n// Cron Parsing (5-field standard: min hour day month weekday)\n// ============================================================================\n\ninterface CronFields {\n minute: Set<number>;\n hour: Set<number>;\n day: Set<number>;\n month: Set<number>;\n weekday: Set<number>;\n}\n\nfunction parseCronField(field: string, min: number, max: number): Set<number> {\n const values = new Set<number>();\n for (const part of field.split(\",\")) {\n if (part === \"*\") {\n for (let i = min; i <= max; i++) values.add(i);\n } else if (part.includes(\"/\")) {\n const [range, stepStr] = part.split(\"/\");\n const step = parseInt(stepStr, 10);\n const start = range === \"*\" ? min : parseInt(range, 10);\n for (let i = start; i <= max; i += step) values.add(i);\n } else if (part.includes(\"-\")) {\n const [lo, hi] = part.split(\"-\").map(Number);\n for (let i = lo; i <= hi; i++) values.add(i);\n } else {\n values.add(parseInt(part, 10));\n }\n }\n return values;\n}\n\nfunction parseCron(expression: string): CronFields {\n const parts = expression.trim().split(/\\s+/);\n if (parts.length !== 5) {\n throw new Error(`Invalid cron expression (expected 5 fields): ${expression}`);\n }\n return {\n minute: parseCronField(parts[0], 0, 59),\n hour: parseCronField(parts[1], 0, 23),\n day: parseCronField(parts[2], 1, 31),\n month: parseCronField(parts[3], 1, 12),\n weekday: parseCronField(parts[4], 0, 6),\n };\n}\n\nfunction cronMatches(fields: CronFields, date: Date): boolean {\n return (\n fields.minute.has(date.getMinutes()) &&\n fields.hour.has(date.getHours()) &&\n fields.day.has(date.getDate()) &&\n fields.month.has(date.getMonth() + 1) &&\n fields.weekday.has(date.getDay())\n );\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createOsHandlers(ctx: OsHandlerContext): OsHandlerResult {\n const cwd = ctx.cwd ?? process.cwd();\n\n // Resource tracking for cleanup\n const watchers: fs.FSWatcher[] = [];\n const intervals: ReturnType<typeof setInterval>[] = [];\n const signalHandlers: Array<{ signal: NodeJS.Signals; handler: () => void }> = [];\n let httpWatchActive = false;\n\n // Debounce configuration: { eventType: ms }\n const debounceConfig = new Map<string, number>();\n const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n function debouncedEmit(eventType: string, payload: EventPayload): void {\n const ms = debounceConfig.get(eventType);\n if (ms !== undefined && ms > 0) {\n const existing = debounceTimers.get(eventType);\n if (existing) clearTimeout(existing);\n debounceTimers.set(\n eventType,\n setTimeout(() => {\n debounceTimers.delete(eventType);\n ctx.emitEvent(eventType, payload);\n }, ms),\n );\n } else {\n ctx.emitEvent(eventType, payload);\n }\n }\n\n // ============================================================================\n // Handler Implementations\n // ============================================================================\n\n // When an author sets `emit: { on_message: \"X\" }` on an os/watch-* effect,\n // we swap the hardcoded default event name for X. Null-safe: absent emit\n // config preserves the legacy names so existing schemas keep working.\n const resolveOnMessage = (emit: OsEmitConfig | undefined, fallback: string): string =>\n emit?.on_message ?? fallback;\n\n const handlers: Partial<EffectHandlers> = {\n osWatchFiles: (\n glob: string,\n options: { recursive?: boolean; debounce?: number },\n emit?: OsEmitConfig,\n ) => {\n const recursive = (options.recursive as boolean) !== false;\n const pattern = globToRegex(glob);\n const eventName = resolveOnMessage(emit, \"OS_FILE_MODIFIED\");\n\n try {\n const watcher = fs.watch(cwd, { recursive }, (_event, filename) => {\n if (filename && pattern.test(filename)) {\n debouncedEmit(eventName, {\n file: filename,\n glob,\n cwd,\n });\n }\n });\n watchers.push(watcher);\n } catch (err) {\n if (emit?.failure) {\n ctx.emitEvent(emit.failure, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n log.warn('watch-files-failed-to-start', { error: err instanceof Error ? err : String(err) });\n }\n },\n\n osWatchProcess: (name: string, subcommand?: string, emit?: OsEmitConfig) => {\n const searchTerm = subcommand ? `${name} ${subcommand}` : name;\n let wasRunning = false;\n // Both start + exit transitions share one event name when emit.on_message\n // is configured (consumers discriminate on the payload's `process` field).\n const startEvent = resolveOnMessage(emit, \"OS_PROCESS_STARTED\");\n const exitEvent = resolveOnMessage(emit, \"OS_PROCESS_EXITED\");\n\n const interval = setInterval(() => {\n let isRunning = false;\n try {\n const result = execSync(`pgrep -f \"${searchTerm}\" 2>/dev/null`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n isRunning = result.trim().length > 0;\n } catch {\n isRunning = false;\n }\n\n if (isRunning && !wasRunning) {\n debouncedEmit(startEvent, { process: name, subcommand: subcommand ?? null });\n } else if (!isRunning && wasRunning) {\n debouncedEmit(exitEvent, { process: name, subcommand: subcommand ?? null });\n }\n wasRunning = isRunning;\n }, 2000);\n\n intervals.push(interval);\n },\n\n osWatchPort: (port: number, protocol: string, emit?: OsEmitConfig) => {\n if (protocol !== \"tcp\") {\n log.warn('watch-port-only-tcp-supported', { protocol });\n return;\n }\n\n let wasOpen = false;\n const openEvent = resolveOnMessage(emit, \"OS_PORT_OPENED\");\n const closeEvent = resolveOnMessage(emit, \"OS_PORT_CLOSED\");\n\n const interval = setInterval(() => {\n const socket = new net.Socket();\n socket.setTimeout(1000);\n\n socket.on(\"connect\", () => {\n socket.destroy();\n if (!wasOpen) {\n wasOpen = true;\n debouncedEmit(openEvent, { port, protocol });\n }\n });\n\n socket.on(\"error\", () => {\n socket.destroy();\n if (wasOpen) {\n wasOpen = false;\n debouncedEmit(closeEvent, { port, protocol });\n }\n });\n\n socket.on(\"timeout\", () => {\n socket.destroy();\n if (wasOpen) {\n wasOpen = false;\n debouncedEmit(closeEvent, { port, protocol });\n }\n });\n\n socket.connect(port, \"127.0.0.1\");\n }, 3000);\n\n intervals.push(interval);\n },\n\n osWatchHttp: (urlPattern: string, method?: string, _emit?: OsEmitConfig) => {\n // HTTP interception requires monkey-patching Node.js module exports (read-only in TS types).\n // The compiled path (backend.rs) generates untyped inline code that handles this.\n // For the interpreted runtime, log a warning.\n if (!httpWatchActive) {\n httpWatchActive = true;\n log.warn('watch-http-compiled-only', {\n pattern: urlPattern,\n method: method ?? null,\n });\n }\n },\n\n osWatchCron: (expression: string, emit?: OsEmitConfig) => {\n let fields: CronFields;\n try {\n fields = parseCron(expression);\n } catch (err) {\n if (emit?.failure) {\n ctx.emitEvent(emit.failure, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n log.warn('watch-cron-invalid-expression', { error: err instanceof Error ? err : String(err) });\n return;\n }\n\n let lastFired = -1;\n const eventName = resolveOnMessage(emit, \"OS_CRON_FIRE\");\n\n const interval = setInterval(() => {\n const now = new Date();\n const minuteKey = now.getFullYear() * 1e8 + now.getMonth() * 1e6 +\n now.getDate() * 1e4 + now.getHours() * 100 + now.getMinutes();\n\n if (minuteKey !== lastFired && cronMatches(fields, now)) {\n lastFired = minuteKey;\n debouncedEmit(eventName, {\n expression,\n firedAt: now.toISOString(),\n });\n }\n }, 1000);\n\n intervals.push(interval);\n },\n\n osWatchSignal: (signal: string, emit?: OsEmitConfig) => {\n const sig = signal.toUpperCase() as NodeJS.Signals;\n // Default name keeps the per-signal suffix (OS_SIGNAL_TERM); a\n // configured on_message drops that convention in favor of the single\n // author-chosen event.\n const handler = () => {\n const eventName = emit?.on_message ?? `OS_SIGNAL_${sig}`;\n debouncedEmit(eventName, { signal: sig });\n };\n\n try {\n process.on(sig, handler);\n signalHandlers.push({ signal: sig, handler });\n } catch (err) {\n if (emit?.failure) {\n ctx.emitEvent(emit.failure, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n log.warn('watch-signal-cannot-listen', { signal: sig, error: err instanceof Error ? err : String(err) });\n }\n },\n\n osWatchEnv: (variable: string, emit?: OsEmitConfig) => {\n let lastValue = process.env[variable];\n const eventName = resolveOnMessage(emit, \"OS_ENV_CHANGED\");\n\n const interval = setInterval(() => {\n const current = process.env[variable];\n if (current !== lastValue) {\n const previous = lastValue;\n lastValue = current;\n debouncedEmit(eventName, {\n variable,\n value: current ?? null,\n previous: previous ?? null,\n });\n }\n }, 1000);\n\n intervals.push(interval);\n },\n\n osDebounce: (ms: number, eventType: string) => {\n debounceConfig.set(eventType, ms);\n },\n };\n\n // ============================================================================\n // Cleanup\n // ============================================================================\n\n function cleanup(): void {\n for (const w of watchers) {\n try { w.close(); } catch { /* already closed */ }\n }\n watchers.length = 0;\n\n for (const i of intervals) {\n clearInterval(i);\n }\n intervals.length = 0;\n\n for (const { signal, handler } of signalHandlers) {\n try { process.removeListener(signal, handler); } catch { /* noop */ }\n }\n signalHandlers.length = 0;\n\n httpWatchActive = false;\n\n // Clear pending debounce timers\n for (const timer of debounceTimers.values()) {\n clearTimeout(timer);\n }\n debounceTimers.clear();\n }\n\n return { handlers, cleanup };\n}\n"]}
1
+ {"version":3,"sources":["../src/createOsHandlers.ts"],"names":[],"mappings":"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","file":"createOsHandlers.js","sourcesContent":["/**\n * OS Trigger Handlers — Server-Side Only\n *\n * Provides Node.js implementations for all 8 os/* operators.\n * Used by OrbitalServerRuntime (interpreted path).\n *\n * NOT exported from the main index.ts because it imports Node.js-only modules.\n * Import directly: import { createOsHandlers } from '@almadar/runtime/createOsHandlers';\n *\n * @packageDocumentation\n */\n\nimport * as fs from \"fs\";\nimport * as net from \"net\";\nimport { execFileSync } from \"child_process\";\nimport { createLogger } from '@almadar/logger';\nimport type { EventPayload, OsEmitConfig } from './types.js';\nimport type { EffectHandlers } from \"./types.js\";\n\nconst log = createLogger('almadar:runtime:os-handlers');\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface OsHandlerContext {\n /** Emit an event on the EventBus */\n emitEvent: (type: string, payload: EventPayload) => void;\n /** Working directory for file watching (defaults to process.cwd()) */\n cwd?: string;\n}\n\nexport interface OsHandlerResult {\n handlers: Partial<EffectHandlers>;\n cleanup: () => void;\n}\n\n// ============================================================================\n// Glob Matching (minimal, no external dependency)\n// ============================================================================\n\nfunction globToRegex(glob: string): RegExp {\n let regex = \"\";\n let i = 0;\n while (i < glob.length) {\n const c = glob[i];\n if (c === \"*\") {\n if (glob[i + 1] === \"*\") {\n // ** matches any path segment\n regex += \".*\";\n i += 2;\n if (glob[i] === \"/\") i++; // skip trailing slash\n continue;\n }\n // * matches anything except /\n regex += \"[^/]*\";\n } else if (c === \"?\") {\n regex += \"[^/]\";\n } else if (c === \".\") {\n regex += \"\\\\.\";\n } else if (c === \"/\" || c === \"-\" || c === \"_\") {\n regex += c;\n } else if (/[{}()[\\]^$+|\\\\]/.test(c)) {\n regex += \"\\\\\" + c;\n } else {\n regex += c;\n }\n i++;\n }\n return new RegExp(\"^\" + regex + \"$\");\n}\n\n// ============================================================================\n// Cron Parsing (5-field standard: min hour day month weekday)\n// ============================================================================\n\ninterface CronFields {\n minute: Set<number>;\n hour: Set<number>;\n day: Set<number>;\n month: Set<number>;\n weekday: Set<number>;\n}\n\nfunction parseCronField(field: string, min: number, max: number): Set<number> {\n const values = new Set<number>();\n for (const part of field.split(\",\")) {\n if (part === \"*\") {\n for (let i = min; i <= max; i++) values.add(i);\n } else if (part.includes(\"/\")) {\n const [range, stepStr] = part.split(\"/\");\n const step = parseInt(stepStr, 10);\n const start = range === \"*\" ? min : parseInt(range, 10);\n for (let i = start; i <= max; i += step) values.add(i);\n } else if (part.includes(\"-\")) {\n const [lo, hi] = part.split(\"-\").map(Number);\n for (let i = lo; i <= hi; i++) values.add(i);\n } else {\n values.add(parseInt(part, 10));\n }\n }\n return values;\n}\n\nfunction parseCron(expression: string): CronFields {\n const parts = expression.trim().split(/\\s+/);\n if (parts.length !== 5) {\n throw new Error(`Invalid cron expression (expected 5 fields): ${expression}`);\n }\n return {\n minute: parseCronField(parts[0], 0, 59),\n hour: parseCronField(parts[1], 0, 23),\n day: parseCronField(parts[2], 1, 31),\n month: parseCronField(parts[3], 1, 12),\n weekday: parseCronField(parts[4], 0, 6),\n };\n}\n\nfunction cronMatches(fields: CronFields, date: Date): boolean {\n return (\n fields.minute.has(date.getMinutes()) &&\n fields.hour.has(date.getHours()) &&\n fields.day.has(date.getDate()) &&\n fields.month.has(date.getMonth() + 1) &&\n fields.weekday.has(date.getDay())\n );\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createOsHandlers(ctx: OsHandlerContext): OsHandlerResult {\n const cwd = ctx.cwd ?? process.cwd();\n\n // Resource tracking for cleanup\n const watchers: fs.FSWatcher[] = [];\n const intervals: ReturnType<typeof setInterval>[] = [];\n const signalHandlers: Array<{ signal: NodeJS.Signals; handler: () => void }> = [];\n let httpWatchActive = false;\n\n // Debounce configuration: { eventType: ms }\n const debounceConfig = new Map<string, number>();\n const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n function debouncedEmit(eventType: string, payload: EventPayload): void {\n const ms = debounceConfig.get(eventType);\n if (ms !== undefined && ms > 0) {\n const existing = debounceTimers.get(eventType);\n if (existing) clearTimeout(existing);\n debounceTimers.set(\n eventType,\n setTimeout(() => {\n debounceTimers.delete(eventType);\n ctx.emitEvent(eventType, payload);\n }, ms),\n );\n } else {\n ctx.emitEvent(eventType, payload);\n }\n }\n\n // ============================================================================\n // Handler Implementations\n // ============================================================================\n\n // When an author sets `emit: { on_message: \"X\" }` on an os/watch-* effect,\n // we swap the hardcoded default event name for X. Null-safe: absent emit\n // config preserves the legacy names so existing schemas keep working.\n const resolveOnMessage = (emit: OsEmitConfig | undefined, fallback: string): string =>\n emit?.on_message ?? fallback;\n\n const handlers: Partial<EffectHandlers> = {\n osWatchFiles: (\n glob: string,\n options: { recursive?: boolean; debounce?: number },\n emit?: OsEmitConfig,\n ) => {\n const recursive = (options.recursive as boolean) !== false;\n const pattern = globToRegex(glob);\n const eventName = resolveOnMessage(emit, \"OS_FILE_MODIFIED\");\n\n try {\n const watcher = fs.watch(cwd, { recursive }, (_event, filename) => {\n if (filename && pattern.test(filename)) {\n debouncedEmit(eventName, {\n file: filename,\n glob,\n cwd,\n });\n }\n });\n watchers.push(watcher);\n } catch (err) {\n if (emit?.failure) {\n ctx.emitEvent(emit.failure, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n log.warn('watch-files-failed-to-start', { error: err instanceof Error ? err : String(err) });\n }\n },\n\n osWatchProcess: (name: string, subcommand?: string, emit?: OsEmitConfig) => {\n const searchTerm = subcommand ? `${name} ${subcommand}` : name;\n // execFileSync below runs pgrep with no shell, so searchTerm can never inject\n // a command; this guard additionally rejects pathological / metacharacter input.\n if (!/^[\\w .\\-/:@]+$/.test(searchTerm)) {\n log.warn('watch-process-invalid-name', { searchTerm });\n return;\n }\n let wasRunning = false;\n // Both start + exit transitions share one event name when emit.on_message\n // is configured (consumers discriminate on the payload's `process` field).\n const startEvent = resolveOnMessage(emit, \"OS_PROCESS_STARTED\");\n const exitEvent = resolveOnMessage(emit, \"OS_PROCESS_EXITED\");\n\n const interval = setInterval(() => {\n let isRunning = false;\n try {\n const result = execFileSync(\"pgrep\", [\"-f\", searchTerm], {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n isRunning = result.trim().length > 0;\n } catch {\n isRunning = false;\n }\n\n if (isRunning && !wasRunning) {\n debouncedEmit(startEvent, { process: name, subcommand: subcommand ?? null });\n } else if (!isRunning && wasRunning) {\n debouncedEmit(exitEvent, { process: name, subcommand: subcommand ?? null });\n }\n wasRunning = isRunning;\n }, 2000);\n\n intervals.push(interval);\n },\n\n osWatchPort: (port: number, protocol: string, emit?: OsEmitConfig) => {\n if (protocol !== \"tcp\") {\n log.warn('watch-port-only-tcp-supported', { protocol });\n return;\n }\n\n let wasOpen = false;\n const openEvent = resolveOnMessage(emit, \"OS_PORT_OPENED\");\n const closeEvent = resolveOnMessage(emit, \"OS_PORT_CLOSED\");\n\n const interval = setInterval(() => {\n const socket = new net.Socket();\n socket.setTimeout(1000);\n\n socket.on(\"connect\", () => {\n socket.destroy();\n if (!wasOpen) {\n wasOpen = true;\n debouncedEmit(openEvent, { port, protocol });\n }\n });\n\n socket.on(\"error\", () => {\n socket.destroy();\n if (wasOpen) {\n wasOpen = false;\n debouncedEmit(closeEvent, { port, protocol });\n }\n });\n\n socket.on(\"timeout\", () => {\n socket.destroy();\n if (wasOpen) {\n wasOpen = false;\n debouncedEmit(closeEvent, { port, protocol });\n }\n });\n\n socket.connect(port, \"127.0.0.1\");\n }, 3000);\n\n intervals.push(interval);\n },\n\n osWatchHttp: (urlPattern: string, method?: string, _emit?: OsEmitConfig) => {\n // HTTP interception requires monkey-patching Node.js module exports (read-only in TS types).\n // The compiled path (backend.rs) generates untyped inline code that handles this.\n // For the interpreted runtime, log a warning.\n if (!httpWatchActive) {\n httpWatchActive = true;\n log.warn('watch-http-compiled-only', {\n pattern: urlPattern,\n method: method ?? null,\n });\n }\n },\n\n osWatchCron: (expression: string, emit?: OsEmitConfig) => {\n let fields: CronFields;\n try {\n fields = parseCron(expression);\n } catch (err) {\n if (emit?.failure) {\n ctx.emitEvent(emit.failure, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n log.warn('watch-cron-invalid-expression', { error: err instanceof Error ? err : String(err) });\n return;\n }\n\n let lastFired = -1;\n const eventName = resolveOnMessage(emit, \"OS_CRON_FIRE\");\n\n const interval = setInterval(() => {\n const now = new Date();\n const minuteKey = now.getFullYear() * 1e8 + now.getMonth() * 1e6 +\n now.getDate() * 1e4 + now.getHours() * 100 + now.getMinutes();\n\n if (minuteKey !== lastFired && cronMatches(fields, now)) {\n lastFired = minuteKey;\n debouncedEmit(eventName, {\n expression,\n firedAt: now.toISOString(),\n });\n }\n }, 1000);\n\n intervals.push(interval);\n },\n\n osWatchSignal: (signal: string, emit?: OsEmitConfig) => {\n const sig = signal.toUpperCase() as NodeJS.Signals;\n // Default name keeps the per-signal suffix (OS_SIGNAL_TERM); a\n // configured on_message drops that convention in favor of the single\n // author-chosen event.\n const handler = () => {\n const eventName = emit?.on_message ?? `OS_SIGNAL_${sig}`;\n debouncedEmit(eventName, { signal: sig });\n };\n\n try {\n process.on(sig, handler);\n signalHandlers.push({ signal: sig, handler });\n } catch (err) {\n if (emit?.failure) {\n ctx.emitEvent(emit.failure, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n log.warn('watch-signal-cannot-listen', { signal: sig, error: err instanceof Error ? err : String(err) });\n }\n },\n\n osWatchEnv: (variable: string, emit?: OsEmitConfig) => {\n let lastValue = process.env[variable];\n const eventName = resolveOnMessage(emit, \"OS_ENV_CHANGED\");\n\n const interval = setInterval(() => {\n const current = process.env[variable];\n if (current !== lastValue) {\n const previous = lastValue;\n lastValue = current;\n debouncedEmit(eventName, {\n variable,\n value: current ?? null,\n previous: previous ?? null,\n });\n }\n }, 1000);\n\n intervals.push(interval);\n },\n\n osDebounce: (ms: number, eventType: string) => {\n debounceConfig.set(eventType, ms);\n },\n };\n\n // ============================================================================\n // Cleanup\n // ============================================================================\n\n function cleanup(): void {\n for (const w of watchers) {\n try { w.close(); } catch { /* already closed */ }\n }\n watchers.length = 0;\n\n for (const i of intervals) {\n clearInterval(i);\n }\n intervals.length = 0;\n\n for (const { signal, handler } of signalHandlers) {\n try { process.removeListener(signal, handler); } catch { /* noop */ }\n }\n signalHandlers.length = 0;\n\n httpWatchActive = false;\n\n // Clear pending debounce timers\n for (const timer of debounceTimers.values()) {\n clearTimeout(timer);\n }\n debounceTimers.clear();\n }\n\n return { handlers, cleanup };\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { B as BindingContext, d as EvaluationContextExtensions, P as PatternProps, b as EffectHandlers, a as EffectContext, f as ExecutionEnvironment, c as EffectResult, T as TraitDefinition } from './types-CjvQG_33.js';
2
- export { E as Effect, e as EventListener, H as HANDLER_MANIFEST, I as IEventBus, R as RuntimeConfig, g as RuntimeEvent, h as TraitState, i as TransitionObserver, j as TransitionResult, U as Unsubscribe } from './types-CjvQG_33.js';
3
- import { U as UnifiedLoaderOptions, S as SchemaLoader, I as ImportChainLike, L as LoadResult, h as LoadedSchema, g as LoadedOrbital } from './OrbitalServerRuntime-CzUrdroI.js';
4
- export { d as EntitySharingMap, e as EventBus, f as EventNamespaceMap, O as OrbitalEventRequest, j as OrbitalEventResponse, l as OrbitalServerRuntimeConfig, P as PreprocessOptions, m as PreprocessResult, n as PreprocessedSchema, o as ProcessEventOptions, R as RegisteredOrbital, p as RuntimeOrbital, q as RuntimeOrbitalSchema, r as RuntimeTrait, t as StateMachineManager, u as collectDeclaredConfigDefaults, v as createInitialTraitState, x as findInitialState, y as findTransition, z as getIsolatedCollectionName, A as getNamespacedEvent, B as isBrowser, D as isElectron, F as isNamespacedEvent, G as isNode, H as normalizeEventKey, J as parseNamespacedEvent, K as preprocessSchema, M as processEvent } from './OrbitalServerRuntime-CzUrdroI.js';
1
+ import { B as BindingContext, E as EvaluationContextExtensions, P as PatternProps, a as EffectHandlers, b as EffectContext, c as ExecutionEnvironment, d as EffectResult, T as TraitDefinition } from './types-cuy5gd29.js';
2
+ export { e as Effect, f as EventListener, H as HANDLER_MANIFEST, I as IEventBus, R as RuntimeConfig, g as RuntimeEvent, h as TraitState, i as TransitionObserver, j as TransitionResult, U as Unsubscribe } from './types-cuy5gd29.js';
3
+ import { U as UnifiedLoaderOptions, S as SchemaLoader, I as ImportChainLike, L as LoadResult, a as LoadedSchema, b as LoadedOrbital } from './OrbitalServerRuntime-CvWqVb68.js';
4
+ export { E as EntitySharingMap, c as EventBus, d as EventNamespaceMap, O as OrbitalEventRequest, e as OrbitalEventResponse, f as OrbitalServerRuntimeConfig, P as PreprocessOptions, g as PreprocessResult, h as PreprocessedSchema, i as ProcessEventOptions, R as RegisteredOrbital, j as RuntimeOrbital, k as RuntimeOrbitalSchema, l as RuntimeTrait, m as StateMachineManager, n as collectDeclaredConfigDefaults, o as createInitialTraitState, p as findInitialState, q as findTransition, r as getIsolatedCollectionName, s as getNamespacedEvent, t as isBrowser, u as isElectron, v as isNamespacedEvent, w as isNode, x as normalizeEventKey, y as parseNamespacedEvent, z as preprocessSchema, A as processEvent } from './OrbitalServerRuntime-CvWqVb68.js';
5
5
  import { EvaluationContext } from '@almadar/evaluator';
6
6
  export { EvaluationContext, createMinimalContext } from '@almadar/evaluator';
7
7
  import { EventPayload, EntityField, EntityRow, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
@@ -346,4 +346,4 @@ interface TransitionObserver {
346
346
  */
347
347
  declare const HANDLER_MANIFEST: Record<ExecutionEnvironment, string[]>;
348
348
 
349
- export { type BindingContext as B, type ConfigContext as C, type Effect as E, HANDLER_MANIFEST as H, type IEventBus as I, type PatternProps as P, type RuntimeConfig as R, type TraitDefinition as T, type Unsubscribe as U, type EffectContext as a, type EffectHandlers as b, type EffectResult as c, type EvaluationContextExtensions as d, type EventListener as e, type ExecutionEnvironment as f, type RuntimeEvent as g, type TraitState as h, type TransitionObserver as i, type TransitionResult as j };
349
+ export { type BindingContext as B, type ConfigContext as C, type EvaluationContextExtensions as E, HANDLER_MANIFEST as H, type IEventBus as I, type PatternProps as P, type RuntimeConfig as R, type TraitDefinition as T, type Unsubscribe as U, type EffectHandlers as a, type EffectContext as b, type ExecutionEnvironment as c, type EffectResult as d, type Effect as e, type EventListener as f, type RuntimeEvent as g, type TraitState as h, type TransitionObserver as i, type TransitionResult as j };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/runtime",
3
- "version": "6.9.2",
3
+ "version": "6.9.3",
4
4
  "description": "Interpreted runtime for Almadar orbital applications (OrbitalServerRuntime)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",