codeweaver 3.0.2 → 3.0.6

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/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "codeweaver",
3
- "version": "3.0.2",
3
+ "version": "3.0.6",
4
4
  "main": "src/main.ts",
5
5
  "bin": {
6
- "codeweaver": "./command.js"
6
+ "codeweaver": "command.js"
7
7
  },
8
8
  "scripts": {
9
9
  "start": "nodemon -r tsconfig-paths/register src/main.ts",
@@ -161,7 +161,7 @@ export default class ProductController {
161
161
  }
162
162
  const product = await this.get(id);
163
163
  if (product != null) {
164
- await assign(updateData, product, ZodProduct);
164
+ await assign(product, updateData, ZodProduct);
165
165
  await productCache.delete(updateData.id.toString());
166
166
  await productsCache.delete("key");
167
167
  } else {
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { ResponseError } from "./error-handling";
2
+ import { parallelMap } from "./parallel/parallel";
3
3
 
4
4
  /**
5
5
  * Strictly assign obj (type T1) to T2 using a Zod schema.
@@ -14,33 +14,28 @@ import { ResponseError } from "./error-handling";
14
14
  * @returns T2 representing the destination after assignment
15
15
  */
16
16
  export default async function assign<T1 extends object, T2 extends object>(
17
- source: T1,
18
17
  destination: T2,
19
- schema?: z.ZodObject<any>
18
+ source: T1,
19
+ destinationSchema?: z.ZodObject<any>
20
20
  ): Promise<T2> {
21
- let keys = Object.keys(schema?.shape ?? destination);
21
+ let keys = Object.keys(destinationSchema?.shape ?? destination);
22
22
 
23
23
  // Iterate schema keys
24
- await Promise.all(
25
- keys.map(async (key) => {
26
- if (source.hasOwnProperty(key)) {
27
- (destination as any)[key] = (source as any)[key];
28
- }
29
- })
30
- );
24
+ await parallelMap(keys, async (key) => {
25
+ if (source.hasOwnProperty(key)) {
26
+ (destination as any)[key] = (source as any)[key];
27
+ }
28
+ });
31
29
 
32
- if (schema != null) {
30
+ if (destinationSchema != null) {
33
31
  // Validate using the schema on the subset (this will also coerce if the schema has transforms)
34
- const parseResult = await schema.safeParseAsync(destination);
32
+ const parseResult = await destinationSchema.safeParseAsync(destination);
35
33
  if (parseResult.success == false) {
36
34
  // Build a descriptive error message from the first issue
37
35
  const issue = parseResult.error.issues?.[0];
38
36
  const path = issue?.path?.length ? issue.path.join(".") : "value";
39
37
  const message = issue?.message ?? "Schema validation failed";
40
- throw new ResponseError(
41
- `Validation failed for "${path}": ${message}`,
42
- 500
43
- );
38
+ throw new Error(`Validation failed for "${path}": ${message}`);
44
39
  }
45
40
  }
46
41
 
@@ -1,5 +1,5 @@
1
1
  import { z, ZodRawShape } from "zod";
2
- import { ResponseError } from "./error-handling";
2
+ import { parallelMap } from "./parallel/parallel";
3
3
 
4
4
  /**
5
5
  * Helper: normalize and validate a numeric string for integer parsing.
@@ -41,10 +41,7 @@ export function stringToInteger(input: string): number {
41
41
  try {
42
42
  return parseIntegerStrict(input);
43
43
  } catch {
44
- throw new ResponseError(
45
- "The input parameter must be a valid integer.",
46
- 400
47
- );
44
+ throw new Error("The input parameter must be a valid integer.");
48
45
  }
49
46
  }
50
47
 
@@ -71,9 +68,8 @@ export function stringToBoolean(input: string): boolean {
71
68
  return false;
72
69
  }
73
70
 
74
- throw new ResponseError(
75
- "The input parameter must be a boolean (e.g., true/false, 1/0).",
76
- 400
71
+ throw new Error(
72
+ "The input parameter must be a boolean (e.g., true/false, 1/0)."
77
73
  );
78
74
  }
79
75
 
@@ -98,7 +94,7 @@ export function stringToNumber(input: string): number {
98
94
 
99
95
  return n;
100
96
  } catch {
101
- throw new ResponseError("The input parameter must be a valid number.", 400);
97
+ throw new Error("The input parameter must be a valid number.");
102
98
  }
103
99
  }
104
100
 
@@ -121,7 +117,7 @@ export async function convert<T1 extends object, T2 extends object>(
121
117
  // Derive the runtime keys from the schema's shape
122
118
  const shape = (schema as any)._def?.shape as ZodRawShape | undefined;
123
119
  if (!shape) {
124
- throw new ResponseError("Provided schema has no shape.", 500);
120
+ throw new Error("Provided schema has no shape.");
125
121
  }
126
122
 
127
123
  const keysSchema = Object.keys(shape) as Array<keyof any>;
@@ -131,13 +127,11 @@ export async function convert<T1 extends object, T2 extends object>(
131
127
  const candidate: any = {};
132
128
 
133
129
  // Iterate schema keys
134
- await Promise.all(
135
- keysSchema.map(async (key) => {
136
- if ((data as any).hasOwnProperty(key)) {
137
- candidate[key] = (data as any)[key];
138
- }
139
- })
140
- );
130
+ await parallelMap(keysSchema, async (key) => {
131
+ if ((data as any).hasOwnProperty(key)) {
132
+ candidate[key] = (data as any)[key];
133
+ }
134
+ });
141
135
 
142
136
  // Validate against the schema
143
137
  if (ignoreValidation) {
@@ -151,10 +145,7 @@ export async function convert<T1 extends object, T2 extends object>(
151
145
  }));
152
146
 
153
147
  // You can log issues or throw a structured error
154
- throw new ResponseError(
155
- `Validation failed: ${JSON.stringify(issues)}`,
156
- 500
157
- );
148
+ throw new Error(`Validation failed: ${JSON.stringify(issues)}`);
158
149
  }
159
150
 
160
151
  // Return the validated data typed as T2
@@ -45,7 +45,9 @@ export class ResponseError extends Error {
45
45
  super(message);
46
46
 
47
47
  // If a custom stack is provided, you might assign it; otherwise, the runtime stack will be used.
48
- if (stack) this.stack = stack;
48
+ if (stack) {
49
+ this.stack = stack;
50
+ }
49
51
  }
50
52
  }
51
53
 
@@ -1,5 +1,3 @@
1
- import { ResponseError } from "../error-handling";
2
-
3
1
  /**
4
2
  * Event callback type for channel send event.
5
3
  * @template T - Type of the value sent through the channel.
@@ -38,7 +36,7 @@ export class Channel<T> {
38
36
  */
39
37
  public async send(value: T): Promise<void> {
40
38
  if (this.closed) {
41
- throw new ResponseError("Channel is closed", 500);
39
+ throw new Error("Channel is closed");
42
40
  }
43
41
  if (this.receivers.length > 0) {
44
42
  const receiver = this.receivers.shift()!;
@@ -62,7 +60,7 @@ export class Channel<T> {
62
60
  return this.queue.shift()!;
63
61
  }
64
62
  if (this.closed) {
65
- throw new ResponseError("Channel is closed", 500);
63
+ throw new Error("Channel is closed");
66
64
  }
67
65
  return await new Promise<T>((resolve) => {
68
66
  this.receivers.push(resolve);
@@ -1,7 +1,20 @@
1
- import { ResponseError } from "../error-handling";
2
- import path from "path";
3
1
  import { WorkerPool } from "./worker-pool";
4
2
 
3
+ /**
4
+ * Creates a setter function that, when invoked, rebinds the captured
5
+ * destination binding to the provided source value.
6
+ *
7
+ * @template T - The type of both `destination` and `source`, constrained to object types.
8
+ * @param {T} destination - The destination value (captured by the closure).
9
+ * @param {T} source - The source value to which `destination` will be rebound when the returned function runs.
10
+ * @returns {() => void} A function that, when called, rebinds the captured `destination` to `source`.
11
+ */
12
+ export function set<T extends object>(destination: T, source: T): () => void {
13
+ return () => {
14
+ destination = source;
15
+ };
16
+ }
17
+
5
18
  /**
6
19
  * Executes multiple asynchronous or synchronous tasks in parallel and returns their results as an array.
7
20
  *
@@ -13,7 +26,9 @@ import { WorkerPool } from "./worker-pool";
13
26
  * const results = await parallel(
14
27
  * () => fetchUser(1),
15
28
  * () => fetchUser(2),
16
- * () => fetchUser(3)
29
+ * fetchProduct,
30
+ * set(user.id, 1),
31
+ * set(user.name, "Bob")
17
32
  * );
18
33
  * console.log(results); // [user1, user2, user3]
19
34
  */
@@ -60,11 +75,11 @@ export async function parallelMapWithConcurrencyLevel<T, U>(
60
75
  concurrencyLevel: number = Infinity
61
76
  ): Promise<U[]> {
62
77
  if (!Array.isArray(items)) {
63
- throw new ResponseError("Items must be an array", 400);
78
+ throw new TypeError("Items must be an array");
64
79
  }
65
80
 
66
81
  if (concurrencyLevel <= 0) {
67
- throw new ResponseError("Concurrency must be greater than 0", 500);
82
+ throw new Error("Concurrency must be greater than 0");
68
83
  }
69
84
 
70
85
  // If concurrency is not finite, use the simple Promise.all approach
@@ -117,11 +132,11 @@ export async function parallelCpuMap<T, R>(
117
132
  throw new Error("concurrency must be greater than 0");
118
133
  }
119
134
 
120
- // Worker pool setup
121
- const workerPath = path.resolve(__dirname, mapperWorkerFilePath);
122
-
123
135
  // Instantiate a concrete pool
124
- const workerPool = new WorkerPool<T, R>(workerPath, concurrencyLevel);
136
+ const workerPool = new WorkerPool<T, R>(
137
+ mapperWorkerFilePath,
138
+ concurrencyLevel
139
+ );
125
140
 
126
141
  try {
127
142
  // Dispatch all items and collect results in order
@@ -1,6 +1,5 @@
1
1
  import { Worker } from "worker_threads";
2
2
  import os from "os";
3
- import { ResponseError } from "../error-handling";
4
3
 
5
4
  export type Task<T> = { id: number; payload: T };
6
5
  export type Result<R> = { id: number; result?: R; error?: string };
@@ -28,9 +27,7 @@ export class WorkerPool<T, R> {
28
27
  if (code !== 0) {
29
28
  // Notify all pending promises about the exit
30
29
  for (const [, p] of this.pending) {
31
- p.reject(
32
- new ResponseError(`Worker ${i} exited with code ${code}`, 500)
33
- );
30
+ p.reject(new Error(`Worker ${i} exited with code ${code}`));
34
31
  }
35
32
  this.pending.clear();
36
33
  }
@@ -56,10 +53,7 @@ export class WorkerPool<T, R> {
56
53
  // This simple version broadcasts the error to all pending tasks for safety.
57
54
  for (const [id, entry] of this.pending) {
58
55
  entry.reject(
59
- new ResponseError(
60
- `Worker ${workerIndex} error: ${err?.message ?? err}`,
61
- 500
62
- )
56
+ new Error(`Worker ${workerIndex} error: ${err?.message ?? err}`)
63
57
  );
64
58
  }
65
59
  this.pending.clear();
@@ -77,8 +71,7 @@ export class WorkerPool<T, R> {
77
71
 
78
72
  // Map all items using a round-robin distribution across workers
79
73
  async mapAll(items: T[]): Promise<R[]> {
80
- if (!Array.isArray(items))
81
- throw new ResponseError("Items must be an array", 400);
74
+ if (!Array.isArray(items)) throw new Error("Items must be an array");
82
75
  const results: R[] = new Array(items.length);
83
76
 
84
77
  const workerCount = this.workers.length;