@workglow/util 0.0.101 → 0.0.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bun.js CHANGED
@@ -144,6 +144,117 @@ class EventEmitter {
144
144
  return () => this.off(event, listener);
145
145
  }
146
146
  }
147
+ // src/logging/ConsoleLogger.ts
148
+ class ConsoleLogger {
149
+ bindings;
150
+ constructor(bindings = {}) {
151
+ this.bindings = bindings;
152
+ }
153
+ info(message, meta) {
154
+ const merged = this.merge(meta);
155
+ if (merged) {
156
+ console.info(message, merged);
157
+ } else {
158
+ console.info(message);
159
+ }
160
+ }
161
+ warn(message, meta) {
162
+ const merged = this.merge(meta);
163
+ if (merged) {
164
+ console.warn(message, merged);
165
+ } else {
166
+ console.warn(message);
167
+ }
168
+ }
169
+ error(message, meta) {
170
+ const merged = this.merge(meta);
171
+ if (merged) {
172
+ console.error(message, merged);
173
+ } else {
174
+ console.error(message);
175
+ }
176
+ }
177
+ debug(message, meta) {
178
+ const merged = this.merge(meta);
179
+ if (merged) {
180
+ console.debug(message, merged);
181
+ } else {
182
+ console.debug(message);
183
+ }
184
+ }
185
+ fatal(err, message, meta) {
186
+ const merged = this.merge(meta);
187
+ if (merged) {
188
+ console.error(message, { ...merged, error: err });
189
+ } else {
190
+ console.error(message, { error: err });
191
+ }
192
+ }
193
+ time(label, meta) {
194
+ const merged = this.merge(meta);
195
+ if (merged) {
196
+ console.info(`[time] ${label}`, merged);
197
+ }
198
+ console.time(label);
199
+ }
200
+ timeEnd(label, meta) {
201
+ console.timeEnd(label);
202
+ const merged = this.merge(meta);
203
+ if (merged) {
204
+ console.info(`[timeEnd] ${label}`, merged);
205
+ }
206
+ }
207
+ group(label, meta) {
208
+ const merged = this.merge(meta);
209
+ if (merged) {
210
+ console.group(label, merged);
211
+ } else {
212
+ console.group(label);
213
+ }
214
+ }
215
+ groupEnd() {
216
+ console.groupEnd();
217
+ }
218
+ child(bindings) {
219
+ return new ConsoleLogger({ ...this.bindings, ...bindings });
220
+ }
221
+ merge(meta) {
222
+ const hasBindings = Object.keys(this.bindings).length > 0;
223
+ if (!hasBindings && !meta)
224
+ return;
225
+ if (!hasBindings)
226
+ return meta;
227
+ if (!meta)
228
+ return this.bindings;
229
+ return { ...this.bindings, ...meta };
230
+ }
231
+ }
232
+ // src/logging/NullLogger.ts
233
+ class NullLogger {
234
+ info(_message, _meta) {}
235
+ error(_message, _meta) {}
236
+ warn(_message, _meta) {}
237
+ debug(_message, _meta) {}
238
+ fatal(_err, _message, _meta) {}
239
+ time(_label, _meta) {}
240
+ timeEnd(_label, _meta) {}
241
+ group(_label, _meta) {}
242
+ groupEnd() {}
243
+ child(_bindings) {
244
+ return this;
245
+ }
246
+ }
247
+ // src/logging/LoggerRegistry.ts
248
+ var LOGGER = createServiceToken("logger");
249
+ if (!globalServiceRegistry.has(LOGGER)) {
250
+ globalServiceRegistry.register(LOGGER, () => new ConsoleLogger, true);
251
+ }
252
+ function getLogger() {
253
+ return globalServiceRegistry.get(LOGGER);
254
+ }
255
+ function setLogger(logger) {
256
+ globalServiceRegistry.registerInstance(LOGGER, logger);
257
+ }
147
258
  // src/utilities/BaseError.ts
148
259
  class BaseError {
149
260
  static type = "BaseError";
@@ -978,6 +1089,169 @@ function areObjectSchemasSemanticallyCompatible(sourceSchema, targetSchema) {
978
1089
  }
979
1090
  // src/json-schema/SchemaValidation.ts
980
1091
  import { compileSchema } from "@sroussey/json-schema-library";
1092
+ // src/json-schema/parsePartialJson.ts
1093
+ function parsePartialJson(text) {
1094
+ const trimmed = text.trim();
1095
+ if (!trimmed)
1096
+ return;
1097
+ try {
1098
+ const result = JSON.parse(trimmed);
1099
+ if (typeof result === "object" && result !== null && !Array.isArray(result)) {
1100
+ return result;
1101
+ }
1102
+ return;
1103
+ } catch {}
1104
+ if (trimmed[0] !== "{")
1105
+ return;
1106
+ const repaired = repairJson(trimmed);
1107
+ if (repaired === undefined)
1108
+ return;
1109
+ try {
1110
+ const result = JSON.parse(repaired);
1111
+ if (typeof result === "object" && result !== null && !Array.isArray(result)) {
1112
+ return result;
1113
+ }
1114
+ return;
1115
+ } catch {
1116
+ return;
1117
+ }
1118
+ }
1119
+ function repairJson(text) {
1120
+ let result = "";
1121
+ let i = 0;
1122
+ const len = text.length;
1123
+ const stack = [];
1124
+ let inString = false;
1125
+ let escaped = false;
1126
+ let lastSafeEnd = 0;
1127
+ while (i < len) {
1128
+ const ch = text[i];
1129
+ if (escaped) {
1130
+ escaped = false;
1131
+ result += ch;
1132
+ i++;
1133
+ continue;
1134
+ }
1135
+ if (ch === "\\") {
1136
+ escaped = true;
1137
+ result += ch;
1138
+ i++;
1139
+ continue;
1140
+ }
1141
+ if (inString) {
1142
+ if (ch === '"') {
1143
+ inString = false;
1144
+ result += ch;
1145
+ i++;
1146
+ lastSafeEnd = result.length;
1147
+ continue;
1148
+ }
1149
+ result += ch;
1150
+ i++;
1151
+ continue;
1152
+ }
1153
+ switch (ch) {
1154
+ case '"':
1155
+ inString = true;
1156
+ result += ch;
1157
+ i++;
1158
+ break;
1159
+ case "{":
1160
+ stack.push("}");
1161
+ result += ch;
1162
+ i++;
1163
+ break;
1164
+ case "[":
1165
+ stack.push("]");
1166
+ result += ch;
1167
+ i++;
1168
+ break;
1169
+ case "}":
1170
+ if (stack.length > 0 && stack[stack.length - 1] === "}") {
1171
+ stack.pop();
1172
+ result += ch;
1173
+ i++;
1174
+ lastSafeEnd = result.length;
1175
+ } else {
1176
+ return closeStack(result, stack);
1177
+ }
1178
+ break;
1179
+ case "]":
1180
+ if (stack.length > 0 && stack[stack.length - 1] === "]") {
1181
+ stack.pop();
1182
+ result += ch;
1183
+ i++;
1184
+ lastSafeEnd = result.length;
1185
+ } else {
1186
+ return closeStack(result, stack);
1187
+ }
1188
+ break;
1189
+ default:
1190
+ result += ch;
1191
+ i++;
1192
+ break;
1193
+ }
1194
+ }
1195
+ if (inString) {
1196
+ result += '"';
1197
+ }
1198
+ if (stack.length === 0) {
1199
+ return result;
1200
+ }
1201
+ return closeStack(cleanTrailing(result), stack);
1202
+ }
1203
+ function cleanTrailing(text) {
1204
+ let s = text.trimEnd();
1205
+ let changed = true;
1206
+ while (changed) {
1207
+ changed = false;
1208
+ const trimmed = s.trimEnd();
1209
+ if (trimmed.endsWith(",")) {
1210
+ s = trimmed.slice(0, -1);
1211
+ changed = true;
1212
+ continue;
1213
+ }
1214
+ if (trimmed.endsWith(":")) {
1215
+ const withoutColon = trimmed.slice(0, -1).trimEnd();
1216
+ if (withoutColon.endsWith('"')) {
1217
+ const keyStart = withoutColon.lastIndexOf('"', withoutColon.length - 2);
1218
+ if (keyStart >= 0) {
1219
+ let before = withoutColon.slice(0, keyStart).trimEnd();
1220
+ if (before.endsWith(",")) {
1221
+ before = before.slice(0, -1);
1222
+ }
1223
+ s = before;
1224
+ changed = true;
1225
+ continue;
1226
+ }
1227
+ }
1228
+ s = withoutColon;
1229
+ changed = true;
1230
+ continue;
1231
+ }
1232
+ const bareTokenMatch = trimmed.match(/,\s*"[^"]*"\s*:\s*(?:tru|fal|nul|true|false|null|[\d.eE+-]+)$/);
1233
+ if (bareTokenMatch) {
1234
+ const valueStr = trimmed.slice(trimmed.lastIndexOf(":") + 1).trim();
1235
+ try {
1236
+ JSON.parse(valueStr);
1237
+ } catch {
1238
+ s = trimmed.slice(0, bareTokenMatch.index).trimEnd();
1239
+ if (s.endsWith(","))
1240
+ s = s.slice(0, -1);
1241
+ changed = true;
1242
+ continue;
1243
+ }
1244
+ }
1245
+ }
1246
+ return s;
1247
+ }
1248
+ function closeStack(text, stack) {
1249
+ let result = text;
1250
+ for (let i = stack.length - 1;i >= 0; i--) {
1251
+ result += stack[i];
1252
+ }
1253
+ return result;
1254
+ }
981
1255
  // src/utilities/Misc.ts
982
1256
  function forceArray(input) {
983
1257
  if (Array.isArray(input))
@@ -1582,43 +1856,12 @@ function normalizeNumberArray(values, throwOnZero = false) {
1582
1856
  return values.map((v) => v / norm);
1583
1857
  }
1584
1858
  // src/worker/WorkerManager.ts
1585
- function extractTransferables(obj) {
1586
- const transferables = [];
1587
- const seen = new WeakSet;
1588
- function findTransferables(value) {
1589
- if (value && typeof value === "object" && seen.has(value)) {
1590
- return;
1591
- }
1592
- if (value && typeof value === "object") {
1593
- seen.add(value);
1594
- }
1595
- if (value instanceof Float32Array || value instanceof Int16Array) {
1596
- transferables.push(value.buffer);
1597
- } else if (value instanceof Uint8Array || value instanceof Uint8ClampedArray || value instanceof Int8Array || value instanceof Uint16Array || value instanceof Int32Array || value instanceof Uint32Array || value instanceof Float64Array || value instanceof BigInt64Array || value instanceof BigUint64Array) {
1598
- transferables.push(value.buffer);
1599
- } else if (typeof OffscreenCanvas !== "undefined" && value instanceof OffscreenCanvas) {
1600
- transferables.push(value);
1601
- } else if (typeof ImageBitmap !== "undefined" && value instanceof ImageBitmap) {
1602
- transferables.push(value);
1603
- } else if (typeof VideoFrame !== "undefined" && value instanceof VideoFrame) {
1604
- transferables.push(value);
1605
- } else if (typeof MessagePort !== "undefined" && value instanceof MessagePort) {
1606
- transferables.push(value);
1607
- } else if (value instanceof ArrayBuffer) {
1608
- transferables.push(value);
1609
- } else if (Array.isArray(value)) {
1610
- value.forEach(findTransferables);
1611
- } else if (value && typeof value === "object") {
1612
- Object.values(value).forEach(findTransferables);
1613
- }
1614
- }
1615
- findTransferables(obj);
1616
- return transferables;
1617
- }
1618
-
1619
1859
  class WorkerManager {
1620
1860
  workers = new Map;
1621
1861
  readyWorkers = new Map;
1862
+ workerFunctions = new Map;
1863
+ workerStreamFunctions = new Map;
1864
+ workerReactiveFunctions = new Map;
1622
1865
  registerWorker(name, worker) {
1623
1866
  if (this.workers.has(name))
1624
1867
  throw new Error(`Worker ${name} is already registered.`);
@@ -1634,6 +1877,9 @@ class WorkerManager {
1634
1877
  const handleReady = (event) => {
1635
1878
  if (event.data?.type === "ready") {
1636
1879
  worker.removeEventListener("message", handleReady);
1880
+ this.workerFunctions.set(name, new Set(event.data.functions ?? []));
1881
+ this.workerStreamFunctions.set(name, new Set(event.data.streamFunctions ?? []));
1882
+ this.workerReactiveFunctions.set(name, new Set(event.data.reactiveFunctions ?? []));
1637
1883
  resolve();
1638
1884
  }
1639
1885
  };
@@ -1652,6 +1898,10 @@ class WorkerManager {
1652
1898
  if (!worker)
1653
1899
  throw new Error(`Worker ${workerName} not found.`);
1654
1900
  await this.readyWorkers.get(workerName);
1901
+ const knownFunctions = this.workerFunctions.get(workerName);
1902
+ if (knownFunctions && !knownFunctions.has(functionName)) {
1903
+ throw new Error(`Function "${functionName}" is not registered on worker "${workerName}".`);
1904
+ }
1655
1905
  return new Promise((resolve, reject) => {
1656
1906
  const requestId = crypto.randomUUID();
1657
1907
  const handleMessage = (event) => {
@@ -1680,8 +1930,7 @@ class WorkerManager {
1680
1930
  options.signal.addEventListener("abort", handleAbort, { once: true });
1681
1931
  }
1682
1932
  const message = { id: requestId, type: "call", functionName, args };
1683
- const transferables = extractTransferables(message);
1684
- worker.postMessage(message, transferables);
1933
+ worker.postMessage(message);
1685
1934
  });
1686
1935
  }
1687
1936
  async callWorkerReactiveFunction(workerName, functionName, args) {
@@ -1689,6 +1938,9 @@ class WorkerManager {
1689
1938
  if (!worker)
1690
1939
  return;
1691
1940
  await this.readyWorkers.get(workerName);
1941
+ const knownReactive = this.workerReactiveFunctions.get(workerName);
1942
+ if (knownReactive && !knownReactive.has(functionName))
1943
+ return;
1692
1944
  return new Promise((resolve) => {
1693
1945
  const requestId = crypto.randomUUID();
1694
1946
  const handleMessage = (event) => {
@@ -1708,8 +1960,7 @@ class WorkerManager {
1708
1960
  };
1709
1961
  worker.addEventListener("message", handleMessage);
1710
1962
  const message = { id: requestId, type: "call", functionName, args, reactive: true };
1711
- const transferables = extractTransferables(message);
1712
- worker.postMessage(message, transferables);
1963
+ worker.postMessage(message);
1713
1964
  });
1714
1965
  }
1715
1966
  async* callWorkerStreamFunction(workerName, functionName, args, options) {
@@ -1717,6 +1968,11 @@ class WorkerManager {
1717
1968
  if (!worker)
1718
1969
  throw new Error(`Worker ${workerName} not found.`);
1719
1970
  await this.readyWorkers.get(workerName);
1971
+ const knownStream = this.workerStreamFunctions.get(workerName);
1972
+ const knownFns = this.workerFunctions.get(workerName);
1973
+ if (knownStream && knownFns && !knownStream.has(functionName) && !knownFns.has(functionName)) {
1974
+ throw new Error(`Function "${functionName}" is not registered on worker "${workerName}".`);
1975
+ }
1720
1976
  const requestId = crypto.randomUUID();
1721
1977
  const queue = [];
1722
1978
  let waiting = null;
@@ -1758,8 +2014,7 @@ class WorkerManager {
1758
2014
  options.signal.addEventListener("abort", handleAbort, { once: true });
1759
2015
  }
1760
2016
  const message = { id: requestId, type: "call", functionName, args, stream: true };
1761
- const transferables = extractTransferables(message);
1762
- worker.postMessage(message, transferables);
2017
+ worker.postMessage(message);
1763
2018
  let completedNormally = false;
1764
2019
  try {
1765
2020
  while (true) {
@@ -1791,7 +2046,7 @@ var WORKER_MANAGER = createServiceToken("worker.manager");
1791
2046
  globalServiceRegistry.register(WORKER_MANAGER, () => new WorkerManager, true);
1792
2047
  // src/worker/WorkerServer.ts
1793
2048
  import { parentPort } from "@workglow/util";
1794
- function extractTransferables2(obj) {
2049
+ function extractTransferables(obj) {
1795
2050
  const transferables = [];
1796
2051
  const seen = new WeakSet;
1797
2052
  function findTransferables(value) {
@@ -1845,8 +2100,9 @@ class WorkerServer {
1845
2100
  return;
1846
2101
  }
1847
2102
  this.completedRequests.add(id);
1848
- const transferables = extractTransferables2(result);
1849
- postMessage({ id, type: "complete", data: result }, transferables);
2103
+ const transferables = extractTransferables(result);
2104
+ const uniqueTransferables = [...new Set(transferables)];
2105
+ postMessage({ id, type: "complete", data: result }, uniqueTransferables);
1850
2106
  };
1851
2107
  postError = (id, errorMessage) => {
1852
2108
  if (this.completedRequests.has(id)) {
@@ -1861,6 +2117,14 @@ class WorkerServer {
1861
2117
  }
1862
2118
  postMessage({ id, type: "stream_chunk", data: event });
1863
2119
  };
2120
+ sendReady() {
2121
+ postMessage({
2122
+ type: "ready",
2123
+ functions: Object.keys(this.functions),
2124
+ streamFunctions: Object.keys(this.streamFunctions),
2125
+ reactiveFunctions: Object.keys(this.reactiveFunctions)
2126
+ });
2127
+ }
1864
2128
  registerFunction(name, fn) {
1865
2129
  this.functions[name] = fn;
1866
2130
  }
@@ -2022,7 +2286,7 @@ var mcpServerConfigSchema = {
2022
2286
  },
2023
2287
  server_url: {
2024
2288
  type: "string",
2025
- format: "uri",
2289
+ format: "string:uri",
2026
2290
  title: "Server URL",
2027
2291
  description: "The URL of the MCP server (for sse and streamable-http transports)"
2028
2292
  },
@@ -2054,12 +2318,14 @@ async function createMcpClient(config, signal) {
2054
2318
  env: config.env
2055
2319
  });
2056
2320
  break;
2057
- case "sse":
2321
+ case "sse": {
2058
2322
  transport = new SSEClientTransport(new URL(config.server_url));
2059
2323
  break;
2060
- case "streamable-http":
2324
+ }
2325
+ case "streamable-http": {
2061
2326
  transport = new StreamableHTTPClientTransport(new URL(config.server_url));
2062
2327
  break;
2328
+ }
2063
2329
  default:
2064
2330
  throw new Error(`Unsupported transport type: ${config.transport}`);
2065
2331
  }
@@ -2069,17 +2335,7 @@ async function createMcpClient(config, signal) {
2069
2335
  client.close().catch(() => {});
2070
2336
  }, { once: true });
2071
2337
  }
2072
- try {
2073
- await client.connect(transport);
2074
- } catch (err) {
2075
- const message = err instanceof Error ? err.message : String(err);
2076
- const url = config.server_url ?? "";
2077
- const is405 = message.includes("405") || message.includes("Method Not Allowed") || typeof err === "object" && err !== null && "status" in err && err.status === 405;
2078
- if (is405) {
2079
- throw new Error(`MCP connection failed with 405 Method Not Allowed for ${url}. ` + `This usually means the server does not accept GET requests. `, { cause: err });
2080
- }
2081
- throw err;
2082
- }
2338
+ await client.connect(transport);
2083
2339
  return { client, transport };
2084
2340
  }
2085
2341
  var mcpClientFactory = {
@@ -2139,8 +2395,10 @@ export {
2139
2395
  sortObject,
2140
2396
  sleep,
2141
2397
  sha256,
2398
+ setLogger,
2142
2399
  serialize,
2143
2400
  registerInputResolver,
2401
+ parsePartialJson,
2144
2402
  parseDataUri,
2145
2403
  parentPort2 as parentPort,
2146
2404
  objectOfArraysAsArrayOfObjects,
@@ -2158,6 +2416,7 @@ export {
2158
2416
  hammingDistance,
2159
2417
  globalServiceRegistry,
2160
2418
  globalContainer,
2419
+ getLogger,
2161
2420
  getInputResolvers,
2162
2421
  forceArray,
2163
2422
  deepEqual,
@@ -2181,8 +2440,10 @@ export {
2181
2440
  TensorType,
2182
2441
  TensorSchema,
2183
2442
  ServiceRegistry,
2443
+ NullLogger,
2184
2444
  NodeDoesntExistError,
2185
2445
  NodeAlreadyExistsError,
2446
+ LOGGER,
2186
2447
  INPUT_RESOLVERS,
2187
2448
  Graph,
2188
2449
  FromSchemaDefaultOptions,
@@ -2191,7 +2452,8 @@ export {
2191
2452
  DirectedAcyclicGraph,
2192
2453
  CycleError,
2193
2454
  Container,
2455
+ ConsoleLogger,
2194
2456
  BaseError
2195
2457
  };
2196
2458
 
2197
- //# debugId=E846D4AA75C881AD64756E2164756E21
2459
+ //# debugId=75EB7BBB8588472C64756E2164756E21