@almadar/runtime 6.4.1 → 6.5.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.
@@ -2,7 +2,9 @@ import './chunk-PZ5AY32C.js';
2
2
  import * as fs from 'fs';
3
3
  import * as net from 'net';
4
4
  import { execSync } from 'child_process';
5
+ import { createLogger } from '@almadar/logger';
5
6
 
7
+ var log = createLogger("almadar:runtime:os-handlers");
6
8
  function globToRegex(glob) {
7
9
  let regex = "";
8
10
  let i = 0;
@@ -113,7 +115,7 @@ function createOsHandlers(ctx) {
113
115
  error: err instanceof Error ? err.message : String(err)
114
116
  });
115
117
  }
116
- console.warn("[os/watch-files] Failed to start watcher:", err);
118
+ log.warn("watch-files-failed-to-start", { error: err instanceof Error ? err : String(err) });
117
119
  }
118
120
  },
119
121
  osWatchProcess: (name, subcommand, emit) => {
@@ -143,7 +145,7 @@ function createOsHandlers(ctx) {
143
145
  },
144
146
  osWatchPort: (port, protocol, emit) => {
145
147
  if (protocol !== "tcp") {
146
- console.warn(`[os/watch-port] Only TCP is supported, got: ${protocol}`);
148
+ log.warn("watch-port-only-tcp-supported", { protocol });
147
149
  return;
148
150
  }
149
151
  let wasOpen = false;
@@ -180,9 +182,10 @@ function createOsHandlers(ctx) {
180
182
  osWatchHttp: (urlPattern, method, _emit) => {
181
183
  if (!httpWatchActive) {
182
184
  httpWatchActive = true;
183
- console.warn(
184
- `[os/watch-http] HTTP interception is only supported in compiled mode. Pattern: ${urlPattern}${method ? `, method: ${method}` : ""}`
185
- );
185
+ log.warn("watch-http-compiled-only", {
186
+ pattern: urlPattern,
187
+ method: method ?? null
188
+ });
186
189
  }
187
190
  },
188
191
  osWatchCron: (expression, emit) => {
@@ -195,7 +198,7 @@ function createOsHandlers(ctx) {
195
198
  error: err instanceof Error ? err.message : String(err)
196
199
  });
197
200
  }
198
- console.warn("[os/watch-cron] Invalid expression:", err);
201
+ log.warn("watch-cron-invalid-expression", { error: err instanceof Error ? err : String(err) });
199
202
  return;
200
203
  }
201
204
  let lastFired = -1;
@@ -228,7 +231,7 @@ function createOsHandlers(ctx) {
228
231
  error: err instanceof Error ? err.message : String(err)
229
232
  });
230
233
  }
231
- console.warn(`[os/watch-signal] Cannot listen for ${sig}:`, err);
234
+ log.warn("watch-signal-cannot-listen", { signal: sig, error: err instanceof Error ? err : String(err) });
232
235
  }
233
236
  },
234
237
  osWatchEnv: (variable, emit) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/createOsHandlers.ts"],"names":[],"mappings":";;;;;AAsCA,SAAS,YAAY,IAAA,EAAsB;AACzC,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OAAO,CAAA,GAAI,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAChB,IAAA,IAAI,MAAM,GAAA,EAAK;AACb,MAAA,IAAI,IAAA,CAAK,CAAA,GAAI,CAAC,CAAA,KAAM,GAAA,EAAK;AAEvB,QAAA,KAAA,IAAS,IAAA;AACT,QAAA,CAAA,IAAK,CAAA;AACL,QAAA,IAAI,IAAA,CAAK,CAAC,CAAA,KAAM,GAAA,EAAK,CAAA,EAAA;AACrB,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,IAAS,OAAA;AAAA,IACX,CAAA,MAAA,IAAW,MAAM,GAAA,EAAK;AACpB,MAAA,KAAA,IAAS,MAAA;AAAA,IACX,CAAA,MAAA,IAAW,MAAM,GAAA,EAAK;AACpB,MAAA,KAAA,IAAS,KAAA;AAAA,IACX,WAAW,CAAA,KAAM,GAAA,IAAO,CAAA,KAAM,GAAA,IAAO,MAAM,GAAA,EAAK;AAC9C,MAAA,KAAA,IAAS,CAAA;AAAA,IACX,CAAA,MAAA,IAAW,iBAAA,CAAkB,IAAA,CAAK,CAAC,CAAA,EAAG;AACpC,MAAA,KAAA,IAAS,IAAA,GAAO,CAAA;AAAA,IAClB,CAAA,MAAO;AACL,MAAA,KAAA,IAAS,CAAA;AAAA,IACX;AACA,IAAA,CAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,IAAI,MAAA,CAAO,GAAA,GAAM,KAAA,GAAQ,GAAG,CAAA;AACrC;AAcA,SAAS,cAAA,CAAe,KAAA,EAAe,GAAA,EAAa,GAAA,EAA0B;AAC5E,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,EAAG;AACnC,IAAA,IAAI,SAAS,GAAA,EAAK;AAChB,MAAA,KAAA,IAAS,IAAI,GAAA,EAAK,CAAA,IAAK,KAAK,CAAA,EAAA,EAAK,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,IAC/C,CAAA,MAAA,IAAW,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AAC7B,MAAA,MAAM,CAAC,KAAA,EAAO,OAAO,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AACvC,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,OAAA,EAAS,EAAE,CAAA;AACjC,MAAA,MAAM,QAAQ,KAAA,KAAU,GAAA,GAAM,GAAA,GAAM,QAAA,CAAS,OAAO,EAAE,CAAA;AACtD,MAAA,KAAA,IAAS,CAAA,GAAI,OAAO,CAAA,IAAK,GAAA,EAAK,KAAK,IAAA,EAAM,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,IACvD,CAAA,MAAA,IAAW,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AAC7B,MAAA,MAAM,CAAC,IAAI,EAAE,CAAA,GAAI,KAAK,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAC3C,MAAA,KAAA,IAAS,IAAI,EAAA,EAAI,CAAA,IAAK,IAAI,CAAA,EAAA,EAAK,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,IAC7C,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,GAAA,CAAI,QAAA,CAAS,IAAA,EAAM,EAAE,CAAC,CAAA;AAAA,IAC/B;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,UAAU,UAAA,EAAgC;AACjD,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA;AAC3C,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgD,UAAU,CAAA,CAAE,CAAA;AAAA,EAC9E;AACA,EAAA,OAAO;AAAA,IACL,QAAQ,cAAA,CAAe,KAAA,CAAM,CAAC,CAAA,EAAG,GAAG,EAAE,CAAA;AAAA,IACtC,MAAM,cAAA,CAAe,KAAA,CAAM,CAAC,CAAA,EAAG,GAAG,EAAE,CAAA;AAAA,IACpC,KAAK,cAAA,CAAe,KAAA,CAAM,CAAC,CAAA,EAAG,GAAG,EAAE,CAAA;AAAA,IACnC,OAAO,cAAA,CAAe,KAAA,CAAM,CAAC,CAAA,EAAG,GAAG,EAAE,CAAA;AAAA,IACrC,SAAS,cAAA,CAAe,KAAA,CAAM,CAAC,CAAA,EAAG,GAAG,CAAC;AAAA,GACxC;AACF;AAEA,SAAS,WAAA,CAAY,QAAoB,IAAA,EAAqB;AAC5D,EAAA,OACE,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,YAAY,CAAA,IACnC,MAAA,CAAO,IAAA,CAAK,IAAI,IAAA,CAAK,QAAA,EAAU,CAAA,IAC/B,OAAO,GAAA,CAAI,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS,CAAA,IAC7B,MAAA,CAAO,KAAA,CAAM,IAAI,IAAA,CAAK,QAAA,EAAS,GAAI,CAAC,KACpC,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,QAAQ,CAAA;AAEpC;AAMO,SAAS,iBAAiB,GAAA,EAAwC;AACvE,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAGnC,EAAA,MAAM,WAA2B,EAAC;AAClC,EAAA,MAAM,YAA8C,EAAC;AACrD,EAAA,MAAM,iBAAyE,EAAC;AAChF,EAAA,IAAI,eAAA,GAAkB,KAAA;AAGtB,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAoB;AAC/C,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAA2C;AAEtE,EAAA,SAAS,aAAA,CAAc,WAAmB,OAAA,EAA6B;AACrE,IAAA,MAAM,EAAA,GAAK,cAAA,CAAe,GAAA,CAAI,SAAS,CAAA;AACvC,IAAA,IAAI,EAAA,KAAO,MAAA,IAAa,EAAA,GAAK,CAAA,EAAG;AAC9B,MAAA,MAAM,QAAA,GAAW,cAAA,CAAe,GAAA,CAAI,SAAS,CAAA;AAC7C,MAAA,IAAI,QAAA,eAAuB,QAAQ,CAAA;AACnC,MAAA,cAAA,CAAe,GAAA;AAAA,QACb,SAAA;AAAA,QACA,WAAW,MAAM;AACf,UAAA,cAAA,CAAe,OAAO,SAAS,CAAA;AAC/B,UAAA,GAAA,CAAI,SAAA,CAAU,WAAW,OAAO,CAAA;AAAA,QAClC,GAAG,EAAE;AAAA,OACP;AAAA,IACF,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,SAAA,CAAU,WAAW,OAAO,CAAA;AAAA,IAClC;AAAA,EACF;AASA,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,EAAgC,QAAA,KACxD,MAAM,UAAA,IAAc,QAAA;AAEtB,EAAA,MAAM,QAAA,GAAoC;AAAA,IACxC,YAAA,EAAc,CACZ,IAAA,EACA,OAAA,EACA,IAAA,KACG;AACH,MAAA,MAAM,SAAA,GAAa,QAAQ,SAAA,KAA0B,KAAA;AACrD,MAAA,MAAM,OAAA,GAAU,YAAY,IAAI,CAAA;AAChC,MAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,EAAM,kBAAkB,CAAA;AAE3D,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAa,SAAM,GAAA,EAAK,EAAE,WAAU,EAAG,CAAC,QAAQ,QAAA,KAAa;AACjE,UAAA,IAAI,QAAA,IAAY,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG;AACtC,YAAA,aAAA,CAAc,SAAA,EAAW;AAAA,cACvB,IAAA,EAAM,QAAA;AAAA,cACN,IAAA;AAAA,cACA;AAAA,aACD,CAAA;AAAA,UACH;AAAA,QACF,CAAC,CAAA;AACD,QAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,MACvB,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,MAAM,OAAA,EAAS;AACjB,UAAA,GAAA,CAAI,SAAA,CAAU,KAAK,OAAA,EAAS;AAAA,YAC1B,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,WACvD,CAAA;AAAA,QACH;AACA,QAAA,OAAA,CAAQ,IAAA,CAAK,6CAA6C,GAAG,CAAA;AAAA,MAC/D;AAAA,IACF,CAAA;AAAA,IAEA,cAAA,EAAgB,CAAC,IAAA,EAAc,UAAA,EAAqB,IAAA,KAAwB;AAC1E,MAAA,MAAM,aAAa,UAAA,GAAa,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,GAAK,IAAA;AAC1D,MAAA,IAAI,UAAA,GAAa,KAAA;AAGjB,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,IAAA,EAAM,oBAAoB,CAAA;AAC9D,MAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,EAAM,mBAAmB,CAAA;AAE5D,MAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,QAAA,IAAI,SAAA,GAAY,KAAA;AAChB,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,QAAA,CAAS,CAAA,UAAA,EAAa,UAAU,CAAA,aAAA,CAAA,EAAiB;AAAA,YAC9D,QAAA,EAAU,OAAA;AAAA,YACV,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM;AAAA,WAC/B,CAAA;AACD,UAAA,SAAA,GAAY,MAAA,CAAO,IAAA,EAAK,CAAE,MAAA,GAAS,CAAA;AAAA,QACrC,CAAA,CAAA,MAAQ;AACN,UAAA,SAAA,GAAY,KAAA;AAAA,QACd;AAEA,QAAA,IAAI,SAAA,IAAa,CAAC,UAAA,EAAY;AAC5B,UAAA,aAAA,CAAc,YAAY,EAAE,OAAA,EAAS,MAAM,UAAA,EAAY,UAAA,IAAc,MAAM,CAAA;AAAA,QAC7E,CAAA,MAAA,IAAW,CAAC,SAAA,IAAa,UAAA,EAAY;AACnC,UAAA,aAAA,CAAc,WAAW,EAAE,OAAA,EAAS,MAAM,UAAA,EAAY,UAAA,IAAc,MAAM,CAAA;AAAA,QAC5E;AACA,QAAA,UAAA,GAAa,SAAA;AAAA,MACf,GAAG,GAAI,CAAA;AAEP,MAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,IACzB,CAAA;AAAA,IAEA,WAAA,EAAa,CAAC,IAAA,EAAc,QAAA,EAAkB,IAAA,KAAwB;AACpE,MAAA,IAAI,aAAa,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,4CAAA,EAA+C,QAAQ,CAAA,CAAE,CAAA;AACtE,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,OAAA,GAAU,KAAA;AACd,MAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,EAAM,gBAAgB,CAAA;AACzD,MAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,IAAA,EAAM,gBAAgB,CAAA;AAE1D,MAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,QAAA,MAAM,MAAA,GAAS,IAAQ,GAAA,CAAA,MAAA,EAAO;AAC9B,QAAA,MAAA,CAAO,WAAW,GAAI,CAAA;AAEtB,QAAA,MAAA,CAAO,EAAA,CAAG,WAAW,MAAM;AACzB,UAAA,MAAA,CAAO,OAAA,EAAQ;AACf,UAAA,IAAI,CAAC,OAAA,EAAS;AACZ,YAAA,OAAA,GAAU,IAAA;AACV,YAAA,aAAA,CAAc,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA;AAAA,UAC7C;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAA,CAAO,EAAA,CAAG,SAAS,MAAM;AACvB,UAAA,MAAA,CAAO,OAAA,EAAQ;AACf,UAAA,IAAI,OAAA,EAAS;AACX,YAAA,OAAA,GAAU,KAAA;AACV,YAAA,aAAA,CAAc,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA;AAAA,UAC9C;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAA,CAAO,EAAA,CAAG,WAAW,MAAM;AACzB,UAAA,MAAA,CAAO,OAAA,EAAQ;AACf,UAAA,IAAI,OAAA,EAAS;AACX,YAAA,OAAA,GAAU,KAAA;AACV,YAAA,aAAA,CAAc,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA;AAAA,UAC9C;AAAA,QACF,CAAC,CAAA;AAED,QAAA,MAAA,CAAO,OAAA,CAAQ,MAAM,WAAW,CAAA;AAAA,MAClC,GAAG,GAAI,CAAA;AAEP,MAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,IACzB,CAAA;AAAA,IAEA,WAAA,EAAa,CAAC,UAAA,EAAoB,MAAA,EAAiB,KAAA,KAAyB;AAI1E,MAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,QAAA,eAAA,GAAkB,IAAA;AAClB,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,kFACY,UAAU,CAAA,EAAG,SAAS,CAAA,UAAA,EAAa,MAAM,KAAK,EAAE,CAAA;AAAA,SAC9D;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IAEA,WAAA,EAAa,CAAC,UAAA,EAAoB,IAAA,KAAwB;AACxD,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,UAAU,UAAU,CAAA;AAAA,MAC/B,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,MAAM,OAAA,EAAS;AACjB,UAAA,GAAA,CAAI,SAAA,CAAU,KAAK,OAAA,EAAS;AAAA,YAC1B,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,WACvD,CAAA;AAAA,QACH;AACA,QAAA,OAAA,CAAQ,IAAA,CAAK,uCAAuC,GAAG,CAAA;AACvD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,SAAA,GAAY,EAAA;AAChB,MAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,EAAM,cAAc,CAAA;AAEvD,MAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,QAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,QAAA,MAAM,YAAY,GAAA,CAAI,WAAA,KAAgB,GAAA,GAAM,GAAA,CAAI,UAAS,GAAI,GAAA,GAC3D,GAAA,CAAI,OAAA,KAAY,GAAA,GAAM,GAAA,CAAI,UAAS,GAAI,GAAA,GAAM,IAAI,UAAA,EAAW;AAE9D,QAAA,IAAI,SAAA,KAAc,SAAA,IAAa,WAAA,CAAY,MAAA,EAAQ,GAAG,CAAA,EAAG;AACvD,UAAA,SAAA,GAAY,SAAA;AACZ,UAAA,aAAA,CAAc,SAAA,EAAW;AAAA,YACvB,UAAA;AAAA,YACA,OAAA,EAAS,IAAI,WAAA;AAAY,WAC1B,CAAA;AAAA,QACH;AAAA,MACF,GAAG,GAAI,CAAA;AAEP,MAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,IACzB,CAAA;AAAA,IAEA,aAAA,EAAe,CAAC,MAAA,EAAgB,IAAA,KAAwB;AACtD,MAAA,MAAM,GAAA,GAAM,OAAO,WAAA,EAAY;AAI/B,MAAA,MAAM,UAAU,MAAM;AACpB,QAAA,MAAM,SAAA,GAAY,IAAA,EAAM,UAAA,IAAc,CAAA,UAAA,EAAa,GAAG,CAAA,CAAA;AACtD,QAAA,aAAA,CAAc,SAAA,EAAW,EAAE,MAAA,EAAQ,GAAA,EAAK,CAAA;AAAA,MAC1C,CAAA;AAEA,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,EAAA,CAAG,KAAK,OAAO,CAAA;AACvB,QAAA,cAAA,CAAe,IAAA,CAAK,EAAE,MAAA,EAAQ,GAAA,EAAK,SAAS,CAAA;AAAA,MAC9C,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,MAAM,OAAA,EAAS;AACjB,UAAA,GAAA,CAAI,SAAA,CAAU,KAAK,OAAA,EAAS;AAAA,YAC1B,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,WACvD,CAAA;AAAA,QACH;AACA,QAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,oCAAA,EAAuC,GAAG,CAAA,CAAA,CAAA,EAAK,GAAG,CAAA;AAAA,MACjE;AAAA,IACF,CAAA;AAAA,IAEA,UAAA,EAAY,CAAC,QAAA,EAAkB,IAAA,KAAwB;AACrD,MAAA,IAAI,SAAA,GAAY,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AACpC,MAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,EAAM,gBAAgB,CAAA;AAEzD,MAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,QAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AACpC,QAAA,IAAI,YAAY,SAAA,EAAW;AACzB,UAAA,MAAM,QAAA,GAAW,SAAA;AACjB,UAAA,SAAA,GAAY,OAAA;AACZ,UAAA,aAAA,CAAc,SAAA,EAAW;AAAA,YACvB,QAAA;AAAA,YACA,OAAO,OAAA,IAAW,IAAA;AAAA,YAClB,UAAU,QAAA,IAAY;AAAA,WACvB,CAAA;AAAA,QACH;AAAA,MACF,GAAG,GAAI,CAAA;AAEP,MAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,IACzB,CAAA;AAAA,IAEA,UAAA,EAAY,CAAC,EAAA,EAAY,SAAA,KAAsB;AAC7C,MAAA,cAAA,CAAe,GAAA,CAAI,WAAW,EAAE,CAAA;AAAA,IAClC;AAAA,GACF;AAMA,EAAA,SAAS,OAAA,GAAgB;AACvB,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,MAAA,IAAI;AAAE,QAAA,CAAA,CAAE,KAAA,EAAM;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAuB;AAAA,IAClD;AACA,IAAA,QAAA,CAAS,MAAA,GAAS,CAAA;AAElB,IAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,MAAA,aAAA,CAAc,CAAC,CAAA;AAAA,IACjB;AACA,IAAA,SAAA,CAAU,MAAA,GAAS,CAAA;AAEnB,IAAA,KAAA,MAAW,EAAE,MAAA,EAAQ,OAAA,EAAQ,IAAK,cAAA,EAAgB;AAChD,MAAA,IAAI;AAAE,QAAA,OAAA,CAAQ,cAAA,CAAe,QAAQ,OAAO,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAa;AAAA,IACtE;AACA,IAAA,cAAA,CAAe,MAAA,GAAS,CAAA;AAExB,IAAA,eAAA,GAAkB,KAAA;AAGlB,IAAA,KAAA,MAAW,KAAA,IAAS,cAAA,CAAe,MAAA,EAAO,EAAG;AAC3C,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AACA,IAAA,cAAA,CAAe,KAAA,EAAM;AAAA,EACvB;AAEA,EAAA,OAAO,EAAE,UAAU,OAAA,EAAQ;AAC7B","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 type { EventPayload, OsEmitConfig } from './types.js';\nimport type { EffectHandlers } from \"./types.js\";\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 console.warn(\"[os/watch-files] Failed to start watcher:\", 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 console.warn(`[os/watch-port] Only TCP is supported, got: ${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 console.warn(\n `[os/watch-http] HTTP interception is only supported in compiled mode. ` +\n `Pattern: ${urlPattern}${method ? `, method: ${method}` : \"\"}`,\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 console.warn(\"[os/watch-cron] Invalid expression:\", 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 console.warn(`[os/watch-signal] Cannot listen for ${sig}:`, 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 { 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"]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
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
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-BtG18R0H.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-BtG18R0H.js';
3
+ import { U as UnifiedLoaderOptions, S as SchemaLoader, I as ImportChainLike, L as LoadResult, a as LoadedSchema, b as LoadedOrbital } from './OrbitalServerRuntime-DhrQA78C.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-DhrQA78C.js';
5
5
  import { EvaluationContext } from '@almadar/evaluator';
6
6
  export { EvaluationContext, createMinimalContext } from '@almadar/evaluator';
7
7
  import { EventPayload, EntityRow, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
@@ -676,11 +676,13 @@ interface PayloadMismatch {
676
676
  * ```ts
677
677
  * const mismatches = validatePayloadShapes(traits, emitsMap);
678
678
  * for (const m of mismatches) {
679
- * console.warn(
680
- * `Trait "${m.listenerTrait}" references @payload.${m.referencedField} ` +
681
- * `for event "${m.event}" but emitter "${m.emitterTrait}" only declares: ` +
682
- * `${m.availableFields.join(', ')}`
683
- * );
679
+ * log.warn('payload-mismatch', {
680
+ * listenerTrait: m.listenerTrait,
681
+ * emitterTrait: m.emitterTrait,
682
+ * event: m.event,
683
+ * referencedField: m.referencedField,
684
+ * availableFields: m.availableFields.join(','),
685
+ * });
684
686
  * }
685
687
  * ```
686
688
  */
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { EffectExecutor, createContextFromBindings } from './chunk-ODKFBOQG.js';
2
- export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, buildEmitsFromTraits, collectDeclaredConfigDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMinimalContext, createMockPersistence, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes } from './chunk-ODKFBOQG.js';
1
+ import { EffectExecutor, createContextFromBindings } from './chunk-VCDCBBYE.js';
2
+ export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, buildEmitsFromTraits, collectDeclaredConfigDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMinimalContext, createMockPersistence, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes } from './chunk-VCDCBBYE.js';
3
3
  import { __export } from './chunk-PZ5AY32C.js';
4
- import { evaluate } from '@almadar/evaluator';
5
4
  import { createLogger } from '@almadar/logger';
5
+ import { evaluate } from '@almadar/evaluator';
6
6
  import { isInlineTrait } from '@almadar/core';
7
7
 
8
- // src/ClientEffectHandlers.ts
8
+ var log = createLogger("almadar:runtime:effects:client");
9
9
  function createClientEffectHandlers(options) {
10
10
  const { eventBus, slotSetter, navigate, notify } = options;
11
11
  return {
@@ -14,13 +14,13 @@ function createClientEffectHandlers(options) {
14
14
  eventBus.emit(prefixedEvent, payload);
15
15
  },
16
16
  persist: async () => {
17
- console.warn("[ClientEffectHandlers] persist is server-side only, ignored on client");
17
+ log.warn("persist-server-side-only");
18
18
  },
19
19
  set: () => {
20
- console.warn("[ClientEffectHandlers] set is server-side only, ignored on client");
20
+ log.warn("set-server-side-only");
21
21
  },
22
22
  callService: async () => {
23
- console.warn("[ClientEffectHandlers] callService is server-side only, ignored on client");
23
+ log.warn("call-service-server-side-only");
24
24
  return {};
25
25
  },
26
26
  renderUI: (slot, pattern, props) => {
@@ -31,10 +31,10 @@ function createClientEffectHandlers(options) {
31
31
  slotSetter.addPattern(slot, pattern, props);
32
32
  },
33
33
  navigate: navigate ?? ((path) => {
34
- console.warn("[ClientEffectHandlers] No navigate handler, ignoring:", path);
34
+ log.warn("navigate-no-handler", { path });
35
35
  }),
36
36
  notify: notify ?? ((msg, type) => {
37
- console.log(`[ClientEffectHandlers] notify (${type}):`, msg);
37
+ log.debug("notify", { type: type ?? null, message: msg });
38
38
  })
39
39
  };
40
40
  }
@@ -60,7 +60,10 @@ function createServerEffectHandlers(opts) {
60
60
  const handlers = {
61
61
  emit: (event, eventPayload, emitSource) => {
62
62
  if (debug) {
63
- console.log(`[ServerEffectHandlers] emit ${event}`, eventPayload);
63
+ effectLog.debug("emit", {
64
+ event,
65
+ payloadKeys: eventPayload ? Object.keys(eventPayload).join(",") : ""
66
+ });
64
67
  }
65
68
  const stamp = emitSource ?? source;
66
69
  eventBus.emit(event, eventPayload, stamp);
@@ -282,9 +285,7 @@ function createServerEffectHandlers(opts) {
282
285
  ...paramsEcho
283
286
  };
284
287
  if (debug) {
285
- console.warn(
286
- `[ServerEffectHandlers] call-service not configured: ${service}.${action} \u2014 using mock result`
287
- );
288
+ effectLog.warn("call-service-not-configured-using-mock", { service, action });
288
289
  }
289
290
  }
290
291
  record({
@@ -336,10 +337,10 @@ function createServerEffectHandlers(opts) {
336
337
  try {
337
338
  return Boolean(evaluate(predicate, ctx));
338
339
  } catch (err) {
339
- console.error(
340
- `[ServerEffectHandlers] fetch filter eval error for ${fetchEntityType}:`,
341
- err
342
- );
340
+ effectLog.error("fetch-filter-eval-error", {
341
+ entityType: fetchEntityType,
342
+ error: err instanceof Error ? err : String(err)
343
+ });
343
344
  return false;
344
345
  }
345
346
  });
@@ -356,10 +357,10 @@ function createServerEffectHandlers(opts) {
356
357
  }
357
358
  return result === null ? null : { rows: result, total };
358
359
  } catch (err) {
359
- console.error(
360
- `[ServerEffectHandlers] fetch error for ${fetchEntityType}:`,
361
- err
362
- );
360
+ effectLog.error("fetch-error", {
361
+ entityType: fetchEntityType,
362
+ error: err instanceof Error ? err : String(err)
363
+ });
363
364
  return null;
364
365
  }
365
366
  },