@resq-sw/helpers 0.1.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.
- package/README.md +218 -0
- package/lib/browser/html-entities.d.ts +34 -0
- package/lib/browser/html-entities.d.ts.map +1 -0
- package/lib/browser/html-entities.js +63 -0
- package/lib/browser/html-entities.js.map +1 -0
- package/lib/browser/index.d.ts +3 -0
- package/lib/browser/index.js +3 -0
- package/lib/browser/platform.d.ts +252 -0
- package/lib/browser/platform.d.ts.map +1 -0
- package/lib/browser/platform.js +272 -0
- package/lib/browser/platform.js.map +1 -0
- package/lib/formatting/date.d.ts +80 -0
- package/lib/formatting/date.d.ts.map +1 -0
- package/lib/formatting/date.js +135 -0
- package/lib/formatting/date.js.map +1 -0
- package/lib/formatting/date.types.d.ts +35 -0
- package/lib/formatting/date.types.d.ts.map +1 -0
- package/lib/formatting/date.types.js +0 -0
- package/lib/formatting/index.d.ts +5 -0
- package/lib/formatting/index.js +4 -0
- package/lib/formatting/number.d.ts +22 -0
- package/lib/formatting/number.d.ts.map +1 -0
- package/lib/formatting/number.js +39 -0
- package/lib/formatting/number.js.map +1 -0
- package/lib/formatting/string.d.ts +22 -0
- package/lib/formatting/string.d.ts.map +1 -0
- package/lib/formatting/string.js +30 -0
- package/lib/formatting/string.js.map +1 -0
- package/lib/helpers.d.ts +142 -0
- package/lib/helpers.d.ts.map +1 -0
- package/lib/helpers.js +159 -0
- package/lib/helpers.js.map +1 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +9 -0
- package/lib/parse-code-path.d.ts +85 -0
- package/lib/parse-code-path.d.ts.map +1 -0
- package/lib/parse-code-path.js +160 -0
- package/lib/parse-code-path.js.map +1 -0
- package/lib/task-exec.d.ts +26 -0
- package/lib/task-exec.d.ts.map +1 -0
- package/lib/task-exec.js +45 -0
- package/lib/task-exec.js.map +1 -0
- package/lib/task-exec.types.d.ts +23 -0
- package/lib/task-exec.types.d.ts.map +1 -0
- package/lib/task-exec.types.js +0 -0
- package/package.json +55 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
//#region src/parse-code-path.ts
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2026 ResQ
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Parses and constructs a formatted string representing the code location, including the file path,
|
|
19
|
+
* associated entity name (such as a function, class, component, or decorator), and human context.
|
|
20
|
+
*
|
|
21
|
+
* The result is useful for debugging, developer logging, and traceability—matching the entity (function, class, etc.)
|
|
22
|
+
* and the context in source code references.
|
|
23
|
+
*
|
|
24
|
+
* @template C The type of the context value.
|
|
25
|
+
* @template T The type of the entity parameter.
|
|
26
|
+
* @param {C} context - A description, situation, or custom value relevant to this code path.
|
|
27
|
+
* @param {T} entity - The entity whose name is included; may be a function, class, object, component, decorator, or their name.
|
|
28
|
+
* @returns {string} A formatted string: "location: <path> @<entity>: <context>".
|
|
29
|
+
* @throws {Error} This function does not throw directly, but see {@link getFilePath}, which may throw in rare stack-trace parsing errors.
|
|
30
|
+
* @example
|
|
31
|
+
* // Function usage
|
|
32
|
+
* function myFunction() {}
|
|
33
|
+
* parseCodePath('initialization', myFunction);
|
|
34
|
+
* // => "location: /current/dir/file.js @myFunction: initialization"
|
|
35
|
+
*
|
|
36
|
+
* // Class usage
|
|
37
|
+
* class MyClass {}
|
|
38
|
+
* parseCodePath('instantiating MyClass', MyClass);
|
|
39
|
+
* // => "location: ... @MyClass: instantiating MyClass"
|
|
40
|
+
*
|
|
41
|
+
* // String as entity
|
|
42
|
+
* parseCodePath('some context', 'EntityAsString');
|
|
43
|
+
* // => "location: ... @EntityAsString: some context"
|
|
44
|
+
*
|
|
45
|
+
|
|
46
|
+
* @see parseCodePathDetailed
|
|
47
|
+
|
|
48
|
+
* @readonly
|
|
49
|
+
* @public
|
|
50
|
+
* @version 1.0.0
|
|
51
|
+
*/
|
|
52
|
+
const parseCodePath = (context, entity) => {
|
|
53
|
+
const entityName = extractEntityName(entity);
|
|
54
|
+
return `location: ${getFilePath()} @${entityName}: ${context}`;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Extracts a standardized name from an entity, supporting functions, classes, instances, symbols, and strings.
|
|
58
|
+
*
|
|
59
|
+
* - For functions or classes, returns the function's/class's `name` or 'AnonymousFunction'
|
|
60
|
+
* - For instances, extracts the class/constructor name
|
|
61
|
+
* - For string entities, returns the string itself
|
|
62
|
+
* - For symbols, returns their string representation
|
|
63
|
+
* - Returns 'UnknownEntity' if no name is found
|
|
64
|
+
*
|
|
65
|
+
* @template T The type of the entity.
|
|
66
|
+
* @param {T} entity - The entity to extract a name from.
|
|
67
|
+
* @returns {string} The extracted name or 'UnknownEntity' if not determinable.
|
|
68
|
+
* @example
|
|
69
|
+
* extractEntityName(function test() {}); // 'test'
|
|
70
|
+
* extractEntityName(class MyClass {}); // 'MyClass'
|
|
71
|
+
* extractEntityName('ManualName'); // 'ManualName'
|
|
72
|
+
* extractEntityName(Symbol('sym')); // 'Symbol(sym)'
|
|
73
|
+
*
|
|
74
|
+
|
|
75
|
+
* @readonly
|
|
76
|
+
* @public
|
|
77
|
+
* @version 1.0.0
|
|
78
|
+
*/
|
|
79
|
+
function extractEntityName(entity) {
|
|
80
|
+
if (typeof entity === "function") return entity.name || "AnonymousFunction";
|
|
81
|
+
if (typeof entity === "object" && entity !== null) {
|
|
82
|
+
const entityConstructor = entity.constructor;
|
|
83
|
+
if (typeof entityConstructor === "function" && entityConstructor.name) return entityConstructor.name;
|
|
84
|
+
}
|
|
85
|
+
if (typeof entity === "string") return entity;
|
|
86
|
+
if (typeof entity === "symbol") return entity.toString();
|
|
87
|
+
return "UnknownEntity";
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Attempts to determine the current file path in both Node.js and browser-like environments.
|
|
91
|
+
* Utilizes `__filename` if available (Node), or parses the call stack when not.
|
|
92
|
+
* Falls back to process.cwd() or 'unknown-location' if all else fails.
|
|
93
|
+
*
|
|
94
|
+
* @returns {string} The current file path, URL, or 'unknown-location'.
|
|
95
|
+
* @throws {Error} Throws if unexpected errors occur in stack trace parsing (caught internally, returns 'unknown-location').
|
|
96
|
+
* @example
|
|
97
|
+
* getFilePath(); // "/Users/user/project/src/utils/formatting/parse-code-path.js"
|
|
98
|
+
*
|
|
99
|
+
|
|
100
|
+
* @web
|
|
101
|
+
* @readonly
|
|
102
|
+
* @private
|
|
103
|
+
* @version 1.0.0
|
|
104
|
+
*/
|
|
105
|
+
function getFilePath() {
|
|
106
|
+
try {
|
|
107
|
+
if (typeof __filename !== "undefined") return __filename;
|
|
108
|
+
const stack = (/* @__PURE__ */ new Error("Stack trace for file path extraction")).stack;
|
|
109
|
+
if (stack) {
|
|
110
|
+
const stackLine = stack.split("\n")[2];
|
|
111
|
+
if (stackLine) {
|
|
112
|
+
const match = /https?:\/\/[^)]+/.exec(stackLine) || /file:\/\/[^)]+/.exec(stackLine) || /at\s+(.+):\d+:\d+/.exec(stackLine);
|
|
113
|
+
if (match) return match[1] || match[0];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return process?.cwd?.() || "unknown-location";
|
|
117
|
+
} catch {
|
|
118
|
+
return "unknown-location";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Parses and constructs a detailed formatted location string, including file path, entity, and context,
|
|
123
|
+
* with optional line number, ISO timestamp, and custom prefix control. Useful for enhanced debugging or audit logs.
|
|
124
|
+
*
|
|
125
|
+
* @template C The type of the context parameter.
|
|
126
|
+
* @template T The type of entity (function, class, etc.).
|
|
127
|
+
* @param {C} context - Context description of the operation or location.
|
|
128
|
+
* @param {T} entity - The entity whose name is included.
|
|
129
|
+
* @param {object} [options] - Optional configuration for output.
|
|
130
|
+
* @param {boolean} [options.includeLineNumber] - If true, appends the call site line number.
|
|
131
|
+
* @param {boolean} [options.includeTimestamp] - If true, appends an ISO 8601 timestamp.
|
|
132
|
+
* @param {string} [options.customPrefix] - Custom prefix instead of default "location".
|
|
133
|
+
* @returns {string} Detailed formatted location string.
|
|
134
|
+
* @throws {Error} Does not throw directly but relies on internal getFilePath logic.
|
|
135
|
+
* @example
|
|
136
|
+
* parseCodePathDetailed('init', MyClass, {includeLineNumber: true, includeTimestamp: true});
|
|
137
|
+
* // => "location: ...:42 [2024-06-01T08:00:00.000Z] @MyClass: init"
|
|
138
|
+
*
|
|
139
|
+
|
|
140
|
+
* @see parseCodePath
|
|
141
|
+
|
|
142
|
+
* @readonly
|
|
143
|
+
* @public
|
|
144
|
+
* @version 1.0.0
|
|
145
|
+
*/
|
|
146
|
+
const parseCodePathDetailed = (context, entity, options = {}) => {
|
|
147
|
+
const entityName = extractEntityName(entity);
|
|
148
|
+
const filePath = getFilePath();
|
|
149
|
+
let locationInfo = `${options.customPrefix || "location"}: ${filePath}`;
|
|
150
|
+
if (options.includeLineNumber) try {
|
|
151
|
+
const lineMatch = ((/* @__PURE__ */ new Error("Stack trace for line number extraction")).stack?.split("\n")[2])?.match(/:(\d+):\d+/);
|
|
152
|
+
if (lineMatch) locationInfo += `:${lineMatch[1]}`;
|
|
153
|
+
} catch {}
|
|
154
|
+
if (options.includeTimestamp) locationInfo += ` [${(/* @__PURE__ */ new Date()).toISOString()}]`;
|
|
155
|
+
return `${locationInfo} @${entityName}: ${context}`;
|
|
156
|
+
};
|
|
157
|
+
//#endregion
|
|
158
|
+
export { parseCodePath, parseCodePathDetailed };
|
|
159
|
+
|
|
160
|
+
//# sourceMappingURL=parse-code-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-code-path.js","names":[],"sources":["../src/parse-code-path.ts"],"sourcesContent":["/**\n * Copyright 2026 ResQ\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Parses and constructs a formatted string representing the code location, including the file path,\n * associated entity name (such as a function, class, component, or decorator), and human context.\n *\n * The result is useful for debugging, developer logging, and traceability—matching the entity (function, class, etc.)\n * and the context in source code references.\n *\n * @template C The type of the context value.\n * @template T The type of the entity parameter.\n * @param {C} context - A description, situation, or custom value relevant to this code path.\n * @param {T} entity - The entity whose name is included; may be a function, class, object, component, decorator, or their name.\n * @returns {string} A formatted string: \"location: <path> @<entity>: <context>\".\n * @throws {Error} This function does not throw directly, but see {@link getFilePath}, which may throw in rare stack-trace parsing errors.\n * @example\n * // Function usage\n * function myFunction() {}\n * parseCodePath('initialization', myFunction);\n * // => \"location: /current/dir/file.js @myFunction: initialization\"\n *\n * // Class usage\n * class MyClass {}\n * parseCodePath('instantiating MyClass', MyClass);\n * // => \"location: ... @MyClass: instantiating MyClass\"\n *\n * // String as entity\n * parseCodePath('some context', 'EntityAsString');\n * // => \"location: ... @EntityAsString: some context\"\n *\n\n * @see parseCodePathDetailed\n\n * @readonly\n * @public\n * @version 1.0.0\n */\nexport const parseCodePath = <C, T>(context: C, entity: T): string => {\n const entityName = extractEntityName(entity);\n const filePath = getFilePath();\n\n return `location: ${filePath} @${entityName}: ${context}`;\n};\n\n/**\n * Extracts a standardized name from an entity, supporting functions, classes, instances, symbols, and strings.\n *\n * - For functions or classes, returns the function's/class's `name` or 'AnonymousFunction'\n * - For instances, extracts the class/constructor name\n * - For string entities, returns the string itself\n * - For symbols, returns their string representation\n * - Returns 'UnknownEntity' if no name is found\n *\n * @template T The type of the entity.\n * @param {T} entity - The entity to extract a name from.\n * @returns {string} The extracted name or 'UnknownEntity' if not determinable.\n * @example\n * extractEntityName(function test() {}); // 'test'\n * extractEntityName(class MyClass {}); // 'MyClass'\n * extractEntityName('ManualName'); // 'ManualName'\n * extractEntityName(Symbol('sym')); // 'Symbol(sym)'\n *\n\n * @readonly\n * @public\n * @version 1.0.0\n */\nfunction extractEntityName<T>(entity: T): string {\n if (typeof entity === 'function') {\n return entity.name || 'AnonymousFunction';\n }\n if (typeof entity === 'object' && entity !== null) {\n const entityConstructor = entity.constructor;\n if (typeof entityConstructor === 'function' && entityConstructor.name) {\n return entityConstructor.name;\n }\n }\n if (typeof entity === 'string') {\n return entity;\n }\n if (typeof entity === 'symbol') {\n return entity.toString();\n }\n return 'UnknownEntity';\n}\n\n/**\n * Attempts to determine the current file path in both Node.js and browser-like environments.\n * Utilizes `__filename` if available (Node), or parses the call stack when not.\n * Falls back to process.cwd() or 'unknown-location' if all else fails.\n *\n * @returns {string} The current file path, URL, or 'unknown-location'.\n * @throws {Error} Throws if unexpected errors occur in stack trace parsing (caught internally, returns 'unknown-location').\n * @example\n * getFilePath(); // \"/Users/user/project/src/utils/formatting/parse-code-path.js\"\n *\n\n * @web\n * @readonly\n * @private\n * @version 1.0.0\n */\nfunction getFilePath(): string {\n try {\n if (typeof __filename !== 'undefined') {\n return __filename;\n }\n const stack = new Error('Stack trace for file path extraction').stack;\n if (stack) {\n const stackLine = stack.split('\\n')[2]; // Get caller's line\n if (stackLine) {\n const match =\n /https?:\\/\\/[^)]+/.exec(stackLine) ||\n /file:\\/\\/[^)]+/.exec(stackLine) ||\n /at\\s+(.+):\\d+:\\d+/.exec(stackLine);\n if (match) {\n return match[1] || match[0];\n }\n }\n }\n return process?.cwd?.() || 'unknown-location';\n } catch {\n return 'unknown-location';\n }\n}\n\n/**\n * Parses and constructs a detailed formatted location string, including file path, entity, and context,\n * with optional line number, ISO timestamp, and custom prefix control. Useful for enhanced debugging or audit logs.\n *\n * @template C The type of the context parameter.\n * @template T The type of entity (function, class, etc.).\n * @param {C} context - Context description of the operation or location.\n * @param {T} entity - The entity whose name is included.\n * @param {object} [options] - Optional configuration for output.\n * @param {boolean} [options.includeLineNumber] - If true, appends the call site line number.\n * @param {boolean} [options.includeTimestamp] - If true, appends an ISO 8601 timestamp.\n * @param {string} [options.customPrefix] - Custom prefix instead of default \"location\".\n * @returns {string} Detailed formatted location string.\n * @throws {Error} Does not throw directly but relies on internal getFilePath logic.\n * @example\n * parseCodePathDetailed('init', MyClass, {includeLineNumber: true, includeTimestamp: true});\n * // => \"location: ...:42 [2024-06-01T08:00:00.000Z] @MyClass: init\"\n *\n\n * @see parseCodePath\n\n * @readonly\n * @public\n * @version 1.0.0\n */\nexport const parseCodePathDetailed = <C, T>(\n context: C,\n entity: T,\n options: {\n includeLineNumber?: boolean;\n includeTimestamp?: boolean;\n customPrefix?: string;\n } = {},\n): string => {\n const entityName = extractEntityName(entity);\n const filePath = getFilePath();\n const prefix = options.customPrefix || 'location';\n\n let locationInfo = `${prefix}: ${filePath}`;\n\n if (options.includeLineNumber) {\n try {\n const stack = new Error('Stack trace for line number extraction').stack;\n const callerLine = stack?.split('\\n')[2];\n const lineMatch = callerLine?.match(/:(\\d+):\\d+/);\n if (lineMatch) {\n locationInfo += `:${lineMatch[1]}`;\n }\n } catch {\n // Ignore errors in line number extraction\n }\n }\n\n if (options.includeTimestamp) {\n locationInfo += ` [${new Date().toISOString()}]`;\n }\n\n return `${locationInfo} @${entityName}: ${context}`;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,MAAa,iBAAuB,SAAY,WAAsB;CACpE,MAAM,aAAa,kBAAkB,OAAO;AAG5C,QAAO,aAFU,aAAa,CAED,IAAI,WAAW,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;AA0BlD,SAAS,kBAAqB,QAAmB;AAC/C,KAAI,OAAO,WAAW,WACpB,QAAO,OAAO,QAAQ;AAExB,KAAI,OAAO,WAAW,YAAY,WAAW,MAAM;EACjD,MAAM,oBAAoB,OAAO;AACjC,MAAI,OAAO,sBAAsB,cAAc,kBAAkB,KAC/D,QAAO,kBAAkB;;AAG7B,KAAI,OAAO,WAAW,SACpB,QAAO;AAET,KAAI,OAAO,WAAW,SACpB,QAAO,OAAO,UAAU;AAE1B,QAAO;;;;;;;;;;;;;;;;;;AAmBT,SAAS,cAAsB;AAC7B,KAAI;AACF,MAAI,OAAO,eAAe,YACxB,QAAO;EAET,MAAM,yBAAQ,IAAI,MAAM,uCAAuC,EAAC;AAChE,MAAI,OAAO;GACT,MAAM,YAAY,MAAM,MAAM,KAAK,CAAC;AACpC,OAAI,WAAW;IACb,MAAM,QACJ,mBAAmB,KAAK,UAAU,IAClC,iBAAiB,KAAK,UAAU,IAChC,oBAAoB,KAAK,UAAU;AACrC,QAAI,MACF,QAAO,MAAM,MAAM,MAAM;;;AAI/B,SAAO,SAAS,OAAO,IAAI;SACrB;AACN,SAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BX,MAAa,yBACX,SACA,QACA,UAII,EAAE,KACK;CACX,MAAM,aAAa,kBAAkB,OAAO;CAC5C,MAAM,WAAW,aAAa;CAG9B,IAAI,eAAe,GAFJ,QAAQ,gBAAgB,WAEV,IAAI;AAEjC,KAAI,QAAQ,kBACV,KAAI;EAGF,MAAM,8BAFQ,IAAI,MAAM,yCAAyC,EAAC,OACxC,MAAM,KAAK,CAAC,KACR,MAAM,aAAa;AACjD,MAAI,UACF,iBAAgB,IAAI,UAAU;SAE1B;AAKV,KAAI,QAAQ,iBACV,iBAAgB,sBAAK,IAAI,MAAM,EAAC,aAAa,CAAC;AAGhD,QAAO,GAAG,aAAa,IAAI,WAAW,IAAI"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/task-exec.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2026 ResQ
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
declare class TaskExec {
|
|
18
|
+
private readonly tasks;
|
|
19
|
+
private handler;
|
|
20
|
+
exec(func: (...args: unknown[]) => unknown, ttl: number): void;
|
|
21
|
+
private handleNext;
|
|
22
|
+
private execNext;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { TaskExec };
|
|
26
|
+
//# sourceMappingURL=task-exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-exec.d.ts","names":[],"sources":["../src/task-exec.ts"],"mappings":";;AAmBA;;;;;;;;;;;;;;cAAa,QAAA;EAAA,iBACM,KAAA;EAAA,QAGT,OAAA;EAER,IAAA,CAAK,IAAA,MAAU,IAAA,yBAA6B,GAAA;EAAA,QAKpC,UAAA;EAAA,QASA,QAAA;AAAA"}
|
package/lib/task-exec.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import TinyQueue from "tinyqueue";
|
|
2
|
+
//#region src/task-exec.ts
|
|
3
|
+
/**
|
|
4
|
+
* Copyright 2026 ResQ
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
var TaskExec = class {
|
|
19
|
+
tasks = new TinyQueue([], (a, b) => a.execTime - b.execTime);
|
|
20
|
+
handler;
|
|
21
|
+
exec(func, ttl) {
|
|
22
|
+
this.tasks.push({
|
|
23
|
+
func,
|
|
24
|
+
execTime: Date.now() + ttl
|
|
25
|
+
});
|
|
26
|
+
this.handleNext();
|
|
27
|
+
}
|
|
28
|
+
handleNext() {
|
|
29
|
+
if (!this.tasks.length) return;
|
|
30
|
+
const { execTime } = this.tasks.peek();
|
|
31
|
+
this.execNext(Math.max(execTime - Date.now(), 0));
|
|
32
|
+
}
|
|
33
|
+
execNext(ttl) {
|
|
34
|
+
clearTimeout(this.handler);
|
|
35
|
+
this.handler = setTimeout(() => {
|
|
36
|
+
const { func } = this.tasks.pop();
|
|
37
|
+
func();
|
|
38
|
+
this.handleNext();
|
|
39
|
+
}, ttl);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
export { TaskExec };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=task-exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-exec.js","names":[],"sources":["../src/task-exec.ts"],"sourcesContent":["/**\n * Copyright 2026 ResQ\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport TinyQueue from 'tinyqueue';\nimport type { TimedTask } from './task-exec.types.js';\n\nexport class TaskExec {\n private readonly tasks = new TinyQueue<TimedTask>([], (a, b) => a.execTime - b.execTime);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private handler: ReturnType<typeof setTimeout> | undefined;\n\n exec(func: (...args: unknown[]) => unknown, ttl: number): void {\n this.tasks.push({ func, execTime: Date.now() + ttl });\n this.handleNext();\n }\n\n private handleNext(): void {\n if (!this.tasks.length) {\n return;\n }\n\n const { execTime } = this.tasks.peek()!;\n this.execNext(Math.max(execTime - Date.now(), 0));\n }\n\n private execNext(ttl: number): void {\n clearTimeout(this.handler);\n this.handler = setTimeout(() => {\n const { func } = this.tasks.pop()!;\n func();\n this.handleNext();\n }, ttl);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,IAAa,WAAb,MAAsB;CACpB,QAAyB,IAAI,UAAqB,EAAE,GAAG,GAAG,MAAM,EAAE,WAAW,EAAE,SAAS;CAGxF;CAEA,KAAK,MAAuC,KAAmB;AAC7D,OAAK,MAAM,KAAK;GAAE;GAAM,UAAU,KAAK,KAAK,GAAG;GAAK,CAAC;AACrD,OAAK,YAAY;;CAGnB,aAA2B;AACzB,MAAI,CAAC,KAAK,MAAM,OACd;EAGF,MAAM,EAAE,aAAa,KAAK,MAAM,MAAM;AACtC,OAAK,SAAS,KAAK,IAAI,WAAW,KAAK,KAAK,EAAE,EAAE,CAAC;;CAGnD,SAAiB,KAAmB;AAClC,eAAa,KAAK,QAAQ;AAC1B,OAAK,UAAU,iBAAiB;GAC9B,MAAM,EAAE,SAAS,KAAK,MAAM,KAAK;AACjC,SAAM;AACN,QAAK,YAAY;KAChB,IAAI"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/task-exec.types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2026 ResQ
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
type TimedTask = {
|
|
18
|
+
func: (...args: unknown[]) => unknown;
|
|
19
|
+
execTime: number;
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { TimedTask };
|
|
23
|
+
//# sourceMappingURL=task-exec.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-exec.types.d.ts","names":[],"sources":["../src/task-exec.types.ts"],"mappings":";;AAgBA;;;;;;;;;;;;;;KAAY,SAAA;EACV,IAAA,MAAU,IAAA;EACV,QAAA;AAAA"}
|
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@resq-sw/helpers",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Functional utilities, type guards, result types, performance measurement, and async task execution",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./lib/index.d.ts",
|
|
10
|
+
"import": "./lib/index.js",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./formatting": {
|
|
14
|
+
"types": "./lib/formatting/index.d.ts",
|
|
15
|
+
"import": "./lib/formatting/index.js",
|
|
16
|
+
"default": "./lib/formatting/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./browser": {
|
|
19
|
+
"types": "./lib/browser/index.d.ts",
|
|
20
|
+
"import": "./lib/browser/index.js",
|
|
21
|
+
"default": "./lib/browser/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"main": "lib/index.js",
|
|
25
|
+
"types": "lib/index.d.ts",
|
|
26
|
+
"files": ["lib", "README.md"],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsdown",
|
|
29
|
+
"test": "vitest run"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@resq-sw/logger": "workspace:*",
|
|
33
|
+
"tinyqueue": "^3.0.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"jsdom": "^29.0.2",
|
|
37
|
+
"tsdown": "^0.21.7",
|
|
38
|
+
"typescript": "5.9.3",
|
|
39
|
+
"vitest": "3.2.4"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public",
|
|
43
|
+
"provenance": true,
|
|
44
|
+
"registry": "https://registry.npmjs.org/"
|
|
45
|
+
},
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/resq-software/npm.git",
|
|
49
|
+
"directory": "packages/helpers"
|
|
50
|
+
},
|
|
51
|
+
"keywords": ["helpers", "utilities", "result-type", "type-guards", "task-queue"],
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=20.19.0"
|
|
54
|
+
}
|
|
55
|
+
}
|