@ecosy/core 0.3.4 → 0.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.
Files changed (85) hide show
  1. package/CHANGELOG.md +163 -0
  2. package/README.md +7 -0
  3. package/agents/skills/ecosy-core-serialize/SKILL.md +93 -0
  4. package/agents/skills/ecosy-core-subscriber/SKILL.md +66 -0
  5. package/dist/cache/disk.d.ts +32 -0
  6. package/dist/cache/disk.js +1 -0
  7. package/dist/cache/disk.mjs +1 -0
  8. package/dist/cache/index.d.ts +17 -0
  9. package/dist/cache/index.js +1 -0
  10. package/dist/cache/index.mjs +1 -0
  11. package/dist/cache/memory.d.ts +19 -0
  12. package/dist/cache/memory.js +1 -0
  13. package/dist/cache/memory.mjs +1 -0
  14. package/dist/cache/redis.d.ts +63 -0
  15. package/dist/cache/redis.js +1 -0
  16. package/dist/cache/redis.mjs +1 -0
  17. package/dist/cache/types.d.ts +35 -0
  18. package/dist/cache/types.js +1 -0
  19. package/dist/cache/types.mjs +1 -0
  20. package/dist/ecosy-core.umd.js +2 -0
  21. package/dist/ecosy-core.umd.js.map +1 -0
  22. package/dist/index.d.ts +0 -9
  23. package/dist/index.js +1 -1
  24. package/dist/index.mjs +1 -1
  25. package/dist/serialize/index.d.ts +62 -0
  26. package/dist/serialize/index.js +1 -0
  27. package/dist/serialize/index.mjs +1 -0
  28. package/dist/serialize/interpolate.d.ts +10 -0
  29. package/dist/serialize/interpolate.js +1 -0
  30. package/dist/serialize/interpolate.mjs +1 -0
  31. package/dist/serialize/json.d.ts +3 -0
  32. package/dist/serialize/json.js +1 -0
  33. package/dist/serialize/json.mjs +1 -0
  34. package/dist/serialize/primitive.d.ts +3 -0
  35. package/dist/serialize/primitive.js +1 -0
  36. package/dist/serialize/primitive.mjs +1 -0
  37. package/dist/serialize/query-string.d.ts +3 -0
  38. package/dist/serialize/query-string.js +1 -0
  39. package/dist/serialize/query-string.mjs +1 -0
  40. package/dist/serialize/types.d.ts +42 -0
  41. package/dist/serialize/types.js +1 -0
  42. package/dist/serialize/types.mjs +1 -0
  43. package/dist/serialize/url.d.ts +3 -0
  44. package/dist/serialize/url.js +1 -0
  45. package/dist/serialize/url.mjs +1 -0
  46. package/dist/syhemo/collectors.d.ts +25 -0
  47. package/dist/syhemo/collectors.js +1 -0
  48. package/dist/syhemo/collectors.mjs +1 -0
  49. package/dist/syhemo/exposition.d.ts +15 -0
  50. package/dist/syhemo/exposition.js +1 -0
  51. package/dist/syhemo/exposition.mjs +1 -0
  52. package/dist/syhemo/index.d.ts +50 -0
  53. package/dist/syhemo/index.js +1 -0
  54. package/dist/syhemo/index.mjs +1 -0
  55. package/dist/{logger.d.ts → syhemo/logger.d.ts} +23 -11
  56. package/dist/syhemo/logger.js +1 -0
  57. package/dist/{logger.mjs → syhemo/logger.mjs} +1 -1
  58. package/dist/syhemo/types.d.ts +114 -0
  59. package/dist/syhemo/types.js +1 -0
  60. package/dist/syhemo/types.mjs +1 -0
  61. package/dist/utilities/index.d.ts +2 -0
  62. package/dist/utilities/index.js +1 -1
  63. package/dist/utilities/index.mjs +1 -1
  64. package/dist/{searchify.d.ts → utilities/searchify.d.ts} +1 -1
  65. package/dist/utilities/searchify.js +1 -0
  66. package/dist/utilities/searchify.mjs +1 -0
  67. package/package.json +52 -39
  68. package/dist/env.d.ts +0 -26
  69. package/dist/env.js +0 -1
  70. package/dist/env.mjs +0 -1
  71. package/dist/http.d.ts +0 -294
  72. package/dist/http.js +0 -1
  73. package/dist/http.mjs +0 -1
  74. package/dist/logger.js +0 -1
  75. package/dist/searchify.js +0 -1
  76. package/dist/searchify.mjs +0 -1
  77. package/dist/serialize.d.ts +0 -80
  78. package/dist/serialize.js +0 -1
  79. package/dist/serialize.mjs +0 -1
  80. package/dist/syhemo.d.ts +0 -102
  81. package/dist/syhemo.js +0 -1
  82. package/dist/syhemo.mjs +0 -1
  83. /package/dist/{slugify.d.ts → utilities/slugify.d.ts} +0 -0
  84. /package/dist/{slugify.js → utilities/slugify.js} +0 -0
  85. /package/dist/{slugify.mjs → utilities/slugify.mjs} +0 -0
@@ -12,24 +12,32 @@ export interface LogEntry {
12
12
  message: string;
13
13
  }
14
14
  /**
15
- * Isomorphic logger with color-coded output.
15
+ * Syhemo's built-in logging stack: colour-coded output plus the shared buffer
16
+ * and counters the monitor reads.
16
17
  *
17
- * - **Server (Node.js)**: Uses ANSI escape codes for terminal coloring.
18
- * - **Browser**: Uses `%c` CSS formatting for DevTools console.
18
+ * This is NOT a general-purpose logger, and it is not re-exported from the
19
+ * package index reach for `@ecosy/logger` for formatters, deliveries and
20
+ * telemetry standards. What lives here exists so that {@link Syhemo} works out
21
+ * of the box: it is one concrete implementation of the `SyhemoLogger` and
22
+ * `SyhemoLogSource` ports, and Syhemo accepts any other.
19
23
  *
20
- * All log entries are buffered in a shared `globalThis` store so that
21
- * {@link Syhemo} can collect them for monitoring.
24
+ * An app that wants its own logs to appear in monitoring snapshots has to
25
+ * write them through something that fills the same buffer — either this class,
26
+ * or its own implementation of `SyhemoLogSource` handed to Syhemo.
27
+ *
28
+ * - **Server (Node.js)**: ANSI escape codes for terminal colour.
29
+ * - **Browser**: `%c` CSS formatting for DevTools.
22
30
  *
23
31
  * @example
24
32
  * ```ts
25
- * const logger = new Logger("MyModule");
33
+ * const logger = new BufferedLogger("MyModule");
26
34
  * logger.log("Server started on port 3000");
27
35
  * logger.warn("Deprecated API used");
28
36
  * logger.error("Connection failed", error);
29
37
  * logger.debug("Payload:", data);
30
38
  * ```
31
39
  */
32
- export declare class Logger {
40
+ export declare class BufferedLogger {
33
41
  private readonly context;
34
42
  /**
35
43
  * @param context - Label shown in log output, e.g. `[MyModule]`.
@@ -51,14 +59,18 @@ export declare class Logger {
51
59
  verbose(message: string, ...args: unknown[]): void;
52
60
  /**
53
61
  * Returns a shallow copy of all buffered log entries (non-destructive).
54
- * Used by {@link Syhemo} to collect logs for monitoring snapshots.
62
+ * Satisfies the `getLogs` half of Syhemo's log source port.
55
63
  */
56
64
  static getLogs(): LogEntry[];
57
65
  /**
58
- * Returns the current error, warn, and total log counts, then resets
59
- * the counters to zero. Used by {@link Syhemo} for per-interval log rate tracking.
66
+ * Running totals since the process started.
67
+ *
68
+ * Non-destructive on purpose: these become Prometheus counters, and a
69
+ * counter that resets when it is read cannot be shared by two consumers and
70
+ * cannot produce a correct rate. The scraper takes the difference between
71
+ * two reads; that is its job, not this one's.
60
72
  */
61
- static drainCounts(): {
73
+ static counts(): {
62
74
  errors: number;
63
75
  warns: number;
64
76
  total: number;
@@ -0,0 +1 @@
1
+ "use strict";const o=()=>"undefined"==typeof window,t="",r="",e="",n="",s={LOG:"color:#22c55e;font-weight:bold",WARN:"color:#eab308;font-weight:bold",ERROR:"color:#ef4444;font-weight:bold",DEBUG:"color:#a855f7;font-weight:bold",VERBOSE:"color:#06b6d4;font-weight:bold"},c="color:inherit;font-weight:normal",i={LOG:"color:#22c55e",WARN:"color:#eab308",ERROR:"color:#ef4444",DEBUG:"color:#a855f7",VERBOSE:"color:#06b6d4"};function a(){return(new Date).toLocaleString("en-US",{month:"2-digit",day:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!0})}const f={LOG:"",WARN:e,ERROR:"",DEBUG:"",VERBOSE:""},l=Symbol.for("@ecosy:logger"),m=globalThis;m[l]||(m[l]={buffer:[],errors:0,warns:0,total:0});const R=m[l];exports.BufferedLogger=class{constructor(o="@ecosy"){this.context=o}format(t,r,...e){const n="ERROR"===t?console.error:"WARN"===t?console.warn:console.log;R.buffer.push({timestamp:Date.now(),level:t,context:this.context,message:r}),R.buffer.length>200&&R.buffer.shift(),R.total++,"ERROR"===t&&R.errors++,"WARN"===t&&R.warns++,o()?this.formatServer(n,t,r,...e):this.formatBrowser(n,t,r,...e)}formatServer(s,c,i,...l){const m=f[c],R=`${n}${a()}${t}`;s(`${`${m}${r}${c.padEnd(7)}${t}`} ${`${e}${o()&&"undefined"!=typeof process?process.pid:0}${t}`} - ${R} ${`${e}[${this.context}]${t}`} ${`${m}${i}${t}`}`,...l)}formatBrowser(o,t,r,...e){o(`%c${t.padEnd(7)}%c - %c${a()}%c %c[${this.context}]%c %c${r}`,s[t],c,"color:#9ca3af;font-weight:normal",c,"color:#eab308;font-weight:normal",c,i[t],...e)}log(o,...t){this.format("LOG",o,...t)}warn(o,...t){this.format("WARN",o,...t)}error(o,...t){this.format("ERROR",o,...t)}debug(o,...t){this.format("DEBUG",o,...t)}verbose(o,...t){this.format("VERBOSE",o,...t)}static getLogs(){return[...R.buffer]}static counts(){return{errors:R.errors,warns:R.warns,total:R.total}}};
@@ -1 +1 @@
1
- const o=()=>"undefined"==typeof window,t="",r="",e="",n="",s={LOG:"color:#22c55e;font-weight:bold",WARN:"color:#eab308;font-weight:bold",ERROR:"color:#ef4444;font-weight:bold",DEBUG:"color:#a855f7;font-weight:bold",VERBOSE:"color:#06b6d4;font-weight:bold"},c="color:inherit;font-weight:normal",a={LOG:"color:#22c55e",WARN:"color:#eab308",ERROR:"color:#ef4444",DEBUG:"color:#a855f7",VERBOSE:"color:#06b6d4"};function i(){return(new Date).toLocaleString("en-US",{month:"2-digit",day:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!0})}const f={LOG:"",WARN:e,ERROR:"",DEBUG:"",VERBOSE:""},l=Symbol.for("@ecosy:logger"),m=globalThis;m[l]||(m[l]={buffer:[],errors:0,warns:0,total:0});const R=m[l];class h{constructor(o="@ecosy"){this.context=o}format(t,r,...e){const n="ERROR"===t?console.error:"WARN"===t?console.warn:console.log;R.buffer.push({timestamp:Date.now(),level:t,context:this.context,message:r}),R.buffer.length>200&&R.buffer.shift(),R.total++,"ERROR"===t&&R.errors++,"WARN"===t&&R.warns++,o()?this.formatServer(n,t,r,...e):this.formatBrowser(n,t,r,...e)}formatServer(s,c,a,...l){const m=f[c],R=`${n}${i()}${t}`;s(`${`${m}${r}${c.padEnd(7)}${t}`} ${`${e}${o()&&"undefined"!=typeof process?process.pid:0}${t}`} - ${R} ${`${e}[${this.context}]${t}`} ${`${m}${a}${t}`}`,...l)}formatBrowser(o,t,r,...e){o(`%c${t.padEnd(7)}%c - %c${i()}%c %c[${this.context}]%c %c${r}`,s[t],c,"color:#9ca3af;font-weight:normal",c,"color:#eab308;font-weight:normal",c,a[t],...e)}log(o,...t){this.format("LOG",o,...t)}warn(o,...t){this.format("WARN",o,...t)}error(o,...t){this.format("ERROR",o,...t)}debug(o,...t){this.format("DEBUG",o,...t)}verbose(o,...t){this.format("VERBOSE",o,...t)}static getLogs(){return[...R.buffer]}static drainCounts(){const o={errors:R.errors,warns:R.warns,total:R.total};return R.errors=0,R.warns=0,R.total=0,o}}export{h as Logger};
1
+ const o=()=>"undefined"==typeof window,t="",r="",e="",n="",c={LOG:"color:#22c55e;font-weight:bold",WARN:"color:#eab308;font-weight:bold",ERROR:"color:#ef4444;font-weight:bold",DEBUG:"color:#a855f7;font-weight:bold",VERBOSE:"color:#06b6d4;font-weight:bold"},s="color:inherit;font-weight:normal",i={LOG:"color:#22c55e",WARN:"color:#eab308",ERROR:"color:#ef4444",DEBUG:"color:#a855f7",VERBOSE:"color:#06b6d4"};function a(){return(new Date).toLocaleString("en-US",{month:"2-digit",day:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!0})}const f={LOG:"",WARN:e,ERROR:"",DEBUG:"",VERBOSE:""},l=Symbol.for("@ecosy:logger"),m=globalThis;m[l]||(m[l]={buffer:[],errors:0,warns:0,total:0});const R=m[l];class h{constructor(o="@ecosy"){this.context=o}format(t,r,...e){const n="ERROR"===t?console.error:"WARN"===t?console.warn:console.log;R.buffer.push({timestamp:Date.now(),level:t,context:this.context,message:r}),R.buffer.length>200&&R.buffer.shift(),R.total++,"ERROR"===t&&R.errors++,"WARN"===t&&R.warns++,o()?this.formatServer(n,t,r,...e):this.formatBrowser(n,t,r,...e)}formatServer(c,s,i,...l){const m=f[s],R=`${n}${a()}${t}`;c(`${`${m}${r}${s.padEnd(7)}${t}`} ${`${e}${o()&&"undefined"!=typeof process?process.pid:0}${t}`} - ${R} ${`${e}[${this.context}]${t}`} ${`${m}${i}${t}`}`,...l)}formatBrowser(o,t,r,...e){o(`%c${t.padEnd(7)}%c - %c${a()}%c %c[${this.context}]%c %c${r}`,c[t],s,"color:#9ca3af;font-weight:normal",s,"color:#eab308;font-weight:normal",s,i[t],...e)}log(o,...t){this.format("LOG",o,...t)}warn(o,...t){this.format("WARN",o,...t)}error(o,...t){this.format("ERROR",o,...t)}debug(o,...t){this.format("DEBUG",o,...t)}verbose(o,...t){this.format("VERBOSE",o,...t)}static getLogs(){return[...R.buffer]}static counts(){return{errors:R.errors,warns:R.warns,total:R.total}}}export{h as BufferedLogger};
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Every shape Syhemo produces or consumes.
3
+ *
4
+ * The metric model below follows Prometheus, so a project that wants a
5
+ * `/metrics` endpoint only has to return what Syhemo already produces — no
6
+ * client library, no registry, no push gateway. That constrains three things
7
+ * which are easy to get wrong and expensive to fix later:
8
+ *
9
+ * - **Base units.** Bytes, seconds, and ratios between 0 and 1. Never MB, ms
10
+ * or percentages: a query that has to know which unit a metric used is a
11
+ * query that will eventually be wrong.
12
+ * - **Counters are monotonic.** `counter` *means* never-decreasing; a scraper
13
+ * computes rates from the difference between two scrapes. A value that
14
+ * resets itself is a gauge wearing a counter's name, and the dashboards it
15
+ * produces look plausible while being wrong.
16
+ * - **Full precision.** Values are not rounded here. Rounding is a display
17
+ * decision, and doing it at the source cannot be undone.
18
+ */
19
+ import type { LogEntry, LogLevel } from "./logger";
20
+ export type { LogEntry, LogLevel };
21
+ /**
22
+ * `counter` only ever grows. `gauge` moves in both directions. `histogram`
23
+ * carries cumulative buckets plus a sum and a count.
24
+ *
25
+ * Summaries are deliberately absent: their quantiles cannot be aggregated
26
+ * across instances, which is the whole reason histograms exist.
27
+ */
28
+ export type MetricType = "counter" | "gauge" | "histogram";
29
+ export type MetricLabels = Record<string, string>;
30
+ /** One cumulative bucket: how many observations were `<= le`. */
31
+ export interface HistogramBucket {
32
+ /** Upper bound, inclusive. `Infinity` renders as `+Inf`. */
33
+ le: number;
34
+ count: number;
35
+ }
36
+ interface MetricBase {
37
+ /** `<namespace>_<subsystem>_<name>_<unit>`, e.g. `process_resident_memory_bytes`. */
38
+ name: string;
39
+ help: string;
40
+ labels?: MetricLabels;
41
+ }
42
+ export interface ScalarMetric extends MetricBase {
43
+ type: "counter" | "gauge";
44
+ value: number;
45
+ }
46
+ export interface HistogramMetric extends MetricBase {
47
+ type: "histogram";
48
+ /** Cumulative: each bucket counts everything at or below its bound. */
49
+ buckets: HistogramBucket[];
50
+ sum: number;
51
+ count: number;
52
+ }
53
+ export type Metric = ScalarMetric | HistogramMetric;
54
+ /** One collection pass. */
55
+ export interface MetricsSnapshot {
56
+ /** Unix milliseconds. */
57
+ timestamp: number;
58
+ metrics: Metric[];
59
+ }
60
+ export interface SyhemoState {
61
+ current: MetricsSnapshot | null;
62
+ snapshots: MetricsSnapshot[];
63
+ logs: LogEntry[];
64
+ started: boolean;
65
+ }
66
+ /** Monotonic log totals since the process started. */
67
+ export interface LogCounts {
68
+ errors: number;
69
+ warns: number;
70
+ total: number;
71
+ }
72
+ /**
73
+ * Where Syhemo writes its own diagnostics.
74
+ *
75
+ * Structurally an `ILogger`, so `@ecosy/logger` — or a bare `console` — is
76
+ * already one. Declared here rather than imported because it is the port the
77
+ * monitor needs, which is what keeps this package free of any dependency on a
78
+ * logging library.
79
+ */
80
+ export interface SyhemoLogger {
81
+ log(message: string, ...args: unknown[]): void;
82
+ warn(message: string, ...args: unknown[]): void;
83
+ error(message: string, ...args: unknown[]): void;
84
+ }
85
+ /**
86
+ * Where Syhemo reads log activity from.
87
+ *
88
+ * A logging library does not normally provide this — writing logs and being
89
+ * able to count them are different jobs — which is why it is a separate port.
90
+ * `BufferedLogger` implements both; pairing `@ecosy/logger` with monitoring
91
+ * means giving it a delivery that fills something shaped like this.
92
+ */
93
+ export interface SyhemoLogSource {
94
+ /** Recent entries. Non-destructive. */
95
+ getLogs(): LogEntry[];
96
+ /**
97
+ * Running totals since the process started.
98
+ *
99
+ * Must be monotonic and non-destructive: these become counters, and a
100
+ * counter that resets when it is read cannot be shared by two consumers and
101
+ * cannot produce a correct rate.
102
+ */
103
+ counts(): LogCounts;
104
+ }
105
+ export interface SyhemoOptions {
106
+ interval?: number;
107
+ db?: () => boolean;
108
+ }
109
+ export interface SyhemoDeps {
110
+ /** Defaults to the built-in `BufferedLogger`. */
111
+ logger?: SyhemoLogger;
112
+ /** Defaults to the built-in buffer behind `BufferedLogger`. */
113
+ source?: SyhemoLogSource;
114
+ }
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+
@@ -10,4 +10,6 @@ export { isLiteralObject, isComplexObject, isObject, isObjectable, hasOwnPropert
10
10
  export { merge } from "./merge";
11
11
  export { isFormData, objectToFormData } from "./formdata";
12
12
  export { MIME_REGEX, sanitizeMime } from "./sanitize-mime";
13
+ export { searchify, type SearchPosition, type SearchResult } from "./searchify";
14
+ export { slugify, DEFAULT_TRANSFORMER, type SlugifyOptions } from "./slugify";
13
15
  export { toString, ucfirst, pascalToKebab } from "./string";
@@ -1 +1 @@
1
- "use strict";var e=require("./clone.js"),r=require("./defer.js"),t=require("./filelist.js"),s=require("./flatten.js"),i=require("./freeze.js"),o=require("./get.js"),a=require("./is-equal.js"),p=require("./is-function.js"),x=require("./object.js"),c=require("./merge.js"),j=require("./formdata.js"),n=require("./sanitize-mime.js"),l=require("./string.js");exports.clone=e.clone,exports.defer=r.defer,exports.deferAsync=r.deferAsync,exports.isFileList=t.isFileList,exports.escapeRegexKey=s.escapeRegexKey,exports.flatten=s.flatten,exports.flattenToArray=s.flattenToArray,exports.freeze=i.freeze,exports.get=o.get,exports.isEqual=a.isEqual,exports.isFunction=p.isFunction,exports.hasOwnProperty=x.hasOwnProperty,exports.isComplexObject=x.isComplexObject,exports.isLiteralObject=x.isLiteralObject,exports.isObject=x.isObject,exports.isObjectable=x.isObjectable,exports.merge=c.merge,exports.isFormData=j.isFormData,exports.objectToFormData=j.objectToFormData,exports.MIME_REGEX=n.MIME_REGEX,exports.sanitizeMime=n.sanitizeMime,exports.pascalToKebab=l.pascalToKebab,exports.toString=l.toString,exports.ucfirst=l.ucfirst;
1
+ "use strict";var e=require("./clone.js"),r=require("./defer.js"),s=require("./filelist.js"),t=require("./flatten.js"),i=require("./freeze.js"),o=require("./get.js"),a=require("./is-equal.js"),p=require("./is-function.js"),x=require("./object.js"),c=require("./merge.js"),u=require("./formdata.js"),j=require("./sanitize-mime.js"),l=require("./searchify.js"),f=require("./slugify.js"),n=require("./string.js");exports.clone=e.clone,exports.defer=r.defer,exports.deferAsync=r.deferAsync,exports.isFileList=s.isFileList,exports.escapeRegexKey=t.escapeRegexKey,exports.flatten=t.flatten,exports.flattenToArray=t.flattenToArray,exports.freeze=i.freeze,exports.get=o.get,exports.isEqual=a.isEqual,exports.isFunction=p.isFunction,exports.hasOwnProperty=x.hasOwnProperty,exports.isComplexObject=x.isComplexObject,exports.isLiteralObject=x.isLiteralObject,exports.isObject=x.isObject,exports.isObjectable=x.isObjectable,exports.merge=c.merge,exports.isFormData=u.isFormData,exports.objectToFormData=u.objectToFormData,exports.MIME_REGEX=j.MIME_REGEX,exports.sanitizeMime=j.sanitizeMime,exports.searchify=l.searchify,exports.DEFAULT_TRANSFORMER=f.DEFAULT_TRANSFORMER,exports.slugify=f.slugify,exports.pascalToKebab=n.pascalToKebab,exports.toString=n.toString,exports.ucfirst=n.ucfirst;
@@ -1 +1 @@
1
- export{clone}from"./clone.mjs";export{defer,deferAsync}from"./defer.mjs";export{isFileList}from"./filelist.mjs";export{escapeRegexKey,flatten,flattenToArray}from"./flatten.mjs";export{freeze}from"./freeze.mjs";export{get}from"./get.mjs";export{isEqual}from"./is-equal.mjs";export{isFunction}from"./is-function.mjs";export{hasOwnProperty,isComplexObject,isLiteralObject,isObject,isObjectable}from"./object.mjs";export{merge}from"./merge.mjs";export{isFormData,objectToFormData}from"./formdata.mjs";export{MIME_REGEX,sanitizeMime}from"./sanitize-mime.mjs";export{pascalToKebab,toString,ucfirst}from"./string.mjs";
1
+ export{clone}from"./clone.mjs";export{defer,deferAsync}from"./defer.mjs";export{isFileList}from"./filelist.mjs";export{escapeRegexKey,flatten,flattenToArray}from"./flatten.mjs";export{freeze}from"./freeze.mjs";export{get}from"./get.mjs";export{isEqual}from"./is-equal.mjs";export{isFunction}from"./is-function.mjs";export{hasOwnProperty,isComplexObject,isLiteralObject,isObject,isObjectable}from"./object.mjs";export{merge}from"./merge.mjs";export{isFormData,objectToFormData}from"./formdata.mjs";export{MIME_REGEX,sanitizeMime}from"./sanitize-mime.mjs";export{searchify}from"./searchify.mjs";export{DEFAULT_TRANSFORMER,slugify}from"./slugify.mjs";export{pascalToKebab,toString,ucfirst}from"./string.mjs";
@@ -32,4 +32,4 @@ export interface SearchResult {
32
32
  * // { matches: ["Brûlée"], positions: [{ start: 6, length: 6 }] }
33
33
  * ```
34
34
  */
35
- export default function searchify(original: string, searchStr: string): SearchResult;
35
+ export declare function searchify(original: string, searchStr: string): SearchResult;
@@ -0,0 +1 @@
1
+ "use strict";var t=require("./slugify.js");const e={separator:"",silent:!0,transformer:Object.assign({},t.DEFAULT_TRANSFORMER)};exports.searchify=function(i,s){const n=t.slugify(s,e),r=n.length,o={matches:[],positions:[]};if(!r)return o;const g=new Map,l=[...i.split("")].map((i,s)=>{let n=g.get(i);return void 0===n&&(n=t.slugify(i,e),g.set(i,n)),{originIndex:s,slugified:n,char:i}}).filter((t,e,i)=>0===e||(" "!==t.char||" "!==i[e-1].char));if(l.length<r)return o;for(let t=0;t<l.length;){const e=l[t];if(""===e.slugified){t++;continue}let s="",g=t,f=!0;for(;s.length<r&&g<l.length;){const t=l[g];if(""!==t.slugified&&(s+=t.slugified,!n.startsWith(s))){f=!1;break}g++}if(f&&s===n){const s=l[g-1],n=i.substring(e.originIndex,s.originIndex+1);o.matches.push(n),o.positions.push({start:e.originIndex,length:n.length}),t=g}else t++}return o};
@@ -0,0 +1 @@
1
+ import{DEFAULT_TRANSFORMER as t,slugify as e}from"./slugify.mjs";const i={separator:"",silent:!0,transformer:Object.assign({},t)};function n(t,n){const s=e(n,i),r=s.length,o={matches:[],positions:[]};if(!r)return o;const g=new Map,l=[...t.split("")].map((t,n)=>{let s=g.get(t);return void 0===s&&(s=e(t,i),g.set(t,s)),{originIndex:n,slugified:s,char:t}}).filter((t,e,i)=>0===e||(" "!==t.char||" "!==i[e-1].char));if(l.length<r)return o;for(let e=0;e<l.length;){const i=l[e];if(""===i.slugified){e++;continue}let n="",g=e,f=!0;for(;n.length<r&&g<l.length;){const t=l[g];if(""!==t.slugified&&(n+=t.slugified,!s.startsWith(n))){f=!1;break}g++}if(f&&n===s){const n=l[g-1],s=t.substring(i.originIndex,n.originIndex+1);o.matches.push(s),o.positions.push({start:i.originIndex,length:s.length}),e=g}else e++}return o}export{n as searchify};
package/package.json CHANGED
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "@ecosy/core",
3
- "version": "0.3.4",
3
+ "version": "0.5.0",
4
4
  "description": "A modular, tree-shakable collection of essential utilities, serialization primitives, and event-driven patterns for modern TypeScript applications",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
9
- "type": "module",
10
9
  "main": "./dist/index.js",
11
10
  "module": "./dist/index.mjs",
11
+ "unpkg": "./dist/ecosy-core.umd.js",
12
12
  "types": "./dist/index.d.ts",
13
13
  "files": [
14
- "dist"
14
+ "dist",
15
+ "agents"
15
16
  ],
16
17
  "exports": {
17
18
  ".": {
@@ -32,47 +33,53 @@
32
33
  "import": "./dist/utilities/index.mjs",
33
34
  "require": "./dist/utilities/index.js"
34
35
  },
36
+ "./cache": {
37
+ "source": "./src/cache/index.ts",
38
+ "types": "./dist/cache/index.d.ts",
39
+ "import": "./dist/cache/index.mjs",
40
+ "require": "./dist/cache/index.js"
41
+ },
35
42
  "./subscriber": {
36
43
  "source": "./src/subscriber.ts",
37
44
  "types": "./dist/subscriber.d.ts",
38
45
  "import": "./dist/subscriber.mjs",
39
46
  "require": "./dist/subscriber.js"
40
47
  },
41
- "./http": {
42
- "source": "./src/http.ts",
43
- "types": "./dist/http.d.ts",
44
- "import": "./dist/http.mjs",
45
- "require": "./dist/http.js"
46
- },
47
- "./logger": {
48
- "source": "./src/logger.ts",
49
- "types": "./dist/logger.d.ts",
50
- "import": "./dist/logger.mjs",
51
- "require": "./dist/logger.js"
52
- },
53
48
  "./syhemo": {
54
- "source": "./src/syhemo.ts",
55
- "types": "./dist/syhemo.d.ts",
56
- "import": "./dist/syhemo.mjs",
57
- "require": "./dist/syhemo.js"
49
+ "source": "./src/syhemo/index.ts",
50
+ "types": "./dist/syhemo/index.d.ts",
51
+ "import": "./dist/syhemo/index.mjs",
52
+ "require": "./dist/syhemo/index.js"
53
+ },
54
+ "./syhemo/logger": {
55
+ "source": "./src/syhemo/logger.ts",
56
+ "types": "./dist/syhemo/logger.d.ts",
57
+ "import": "./dist/syhemo/logger.mjs",
58
+ "require": "./dist/syhemo/logger.js"
58
59
  },
59
60
  "./serialize": {
60
- "source": "./src/serialize.ts",
61
- "types": "./dist/serialize.d.ts",
62
- "import": "./dist/serialize.mjs",
63
- "require": "./dist/serialize.js"
61
+ "source": "./src/serialize/index.ts",
62
+ "types": "./dist/serialize/index.d.ts",
63
+ "import": "./dist/serialize/index.mjs",
64
+ "require": "./dist/serialize/index.js"
65
+ },
66
+ "./serialize/*": {
67
+ "source": "./src/serialize/*.ts",
68
+ "types": "./dist/serialize/*.d.ts",
69
+ "import": "./dist/serialize/*.mjs",
70
+ "require": "./dist/serialize/*.js"
64
71
  },
65
72
  "./slugify": {
66
- "source": "./src/slugify.ts",
67
- "types": "./dist/slugify.d.ts",
68
- "import": "./dist/slugify.mjs",
69
- "require": "./dist/slugify.js"
73
+ "source": "./src/utilities/slugify.ts",
74
+ "types": "./dist/utilities/slugify.d.ts",
75
+ "import": "./dist/utilities/slugify.mjs",
76
+ "require": "./dist/utilities/slugify.js"
70
77
  },
71
78
  "./searchify": {
72
- "source": "./src/searchify.ts",
73
- "types": "./dist/searchify.d.ts",
74
- "import": "./dist/searchify.mjs",
75
- "require": "./dist/searchify.js"
79
+ "source": "./src/utilities/searchify.ts",
80
+ "types": "./dist/utilities/searchify.d.ts",
81
+ "import": "./dist/utilities/searchify.mjs",
82
+ "require": "./dist/utilities/searchify.js"
76
83
  }
77
84
  },
78
85
  "scripts": {
@@ -106,17 +113,23 @@
106
113
  "@eslint/js": "^10.0.1",
107
114
  "@rollup/plugin-terser": "^1.0.0",
108
115
  "@rollup/plugin-typescript": "^12.3.0",
109
- "@types/node": "^25.6.0",
110
- "@typescript-eslint/eslint-plugin": "^8.57.1",
111
- "@typescript-eslint/parser": "^8.57.1",
112
- "eslint": "^10.1.0",
116
+ "@types/node": "^26.2.0",
117
+ "@typescript-eslint/eslint-plugin": "^8.67.0",
118
+ "@typescript-eslint/parser": "^8.67.0",
119
+ "eslint": "^10.9.0",
113
120
  "eslint-config-prettier": "^10.1.8",
114
- "eslint-plugin-prettier": "^5.5.5",
121
+ "eslint-plugin-prettier": "^5.5.6",
115
122
  "glob": "^13.0.6",
116
- "prettier": "^3.8.1",
123
+ "prettier": "^3.9.6",
117
124
  "rimraf": "^6.1.3",
118
- "rollup": "^4.59.1",
125
+ "rollup": "^4.62.5",
119
126
  "tslib": "^2.8.1",
120
- "typescript": "^6.0.2"
127
+ "typescript": "6"
128
+ },
129
+ "agents": {
130
+ "skills": [
131
+ "$this://agents/skills/ecosy-core-subscriber/SKILL.md",
132
+ "$this://agents/skills/ecosy-core-serialize/SKILL.md"
133
+ ]
121
134
  }
122
135
  }
package/dist/env.d.ts DELETED
@@ -1,26 +0,0 @@
1
- export type EnvSource = Record<string, string | undefined>;
2
- /**
3
- * Returns an env source object for the current runtime.
4
- * Called once per `getEnv` invocation to resolve the global source.
5
- */
6
- export type EnvGetter = () => EnvSource;
7
- /**
8
- * Read an environment variable across runtimes.
9
- *
10
- * @example
11
- * ```ts
12
- * // Basic — uses getter (default: process.env → import.meta.env)
13
- * getEnv("API_URL", "/api")
14
- *
15
- * // Per-call source (e.g. Hono ctx.env)
16
- * getEnv("API_URL", "/api", ctx.env)
17
- *
18
- * // Custom getter for a specific runtime
19
- * getEnv.getter(() => Deno.env.toObject());
20
- * ```
21
- */
22
- export declare function getEnv(key: string, defaultValue?: string, ...sources: Array<EnvSource | undefined>): string | undefined;
23
- export declare namespace getEnv {
24
- var _getter: EnvGetter;
25
- var getter: (fn: EnvGetter) => void;
26
- }
package/dist/env.js DELETED
@@ -1 +0,0 @@
1
- "use strict";var e=require("./utilities/object.js");function t(e,n,...i){for(const t of i)if(t&&e in t&&void 0!==t[e])return t[e];const r=t._getter();return e in r&&void 0!==r[e]?r[e]:n}t._getter=function(){if("undefined"!=typeof globalThis&&"process"in globalThis){const t=globalThis.process;if((null==t?void 0:t.env)&&e.isLiteralObject(t.env))return t.env}try{const t=new Function("return import.meta")();if((null==t?void 0:t.env)&&e.isLiteralObject(t.env))return t.env}catch(e){}return{}},t.getter=e=>{t._getter=e},exports.getEnv=t;
package/dist/env.mjs DELETED
@@ -1 +0,0 @@
1
- import{isLiteralObject as t}from"./utilities/object.mjs";function e(t,n,...o){for(const e of o)if(e&&t in e&&void 0!==e[t])return e[t];const r=e._getter();return t in r&&void 0!==r[t]?r[t]:n}e._getter=function(){if("undefined"!=typeof globalThis&&"process"in globalThis){const e=globalThis.process;if((null==e?void 0:e.env)&&t(e.env))return e.env}try{const e=new Function("return import.meta")();if((null==e?void 0:e.env)&&t(e.env))return e.env}catch(t){}return{}},e.getter=t=>{e._getter=t};export{e as getEnv};