@ultrst-armada/kloks 1.4.3 → 1.4.4

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 (79) hide show
  1. package/package.json +8 -20
  2. package/packages/audio-midi/dist/index.d.ts +23 -14
  3. package/packages/audio-midi/dist/index.js +170 -45
  4. package/packages/audio-midi/kloks.manifest.json +8 -8
  5. package/packages/audio-midi/package.json +1 -1
  6. package/packages/backend/dist/{WebSocketTransport-CxUzUfwl.d.ts → WebSocketTransport-CHmkJ0tj.d.ts} +109 -2
  7. package/packages/backend/dist/auth/index.js +6 -6
  8. package/packages/backend/dist/chunk-5336MTXD.js +597 -0
  9. package/packages/backend/dist/{chunk-T3NYNBDC.js → chunk-5E6JRFUH.js} +201 -3
  10. package/packages/backend/dist/{chunk-XTWHEZWS.js → chunk-7B24ZWB3.js} +16 -1
  11. package/packages/backend/dist/{chunk-DZ4ZGIZM.js → chunk-JXUSBKJ2.js} +91 -654
  12. package/packages/backend/dist/{chunk-FO6WYLW4.js → chunk-KI3LHMUN.js} +133 -46
  13. package/packages/backend/dist/{chunk-4ZFXEFOE.js → chunk-MPYASJ5A.js} +2 -87
  14. package/packages/backend/dist/{chunk-KX3OTBQ3.js → chunk-OZDYAEH4.js} +0 -114
  15. package/packages/backend/dist/chunk-TY32TUNI.js +376 -0
  16. package/packages/backend/dist/chunk-VDROUXFT.js +116 -0
  17. package/packages/backend/dist/chunk-ZDH4XI7W.js +140 -0
  18. package/packages/backend/dist/client/index.d.ts +2 -3
  19. package/packages/backend/dist/connectivity/index.d.ts +18 -6
  20. package/packages/backend/dist/connectivity/index.js +3 -7
  21. package/packages/backend/dist/index.d.ts +3 -6
  22. package/packages/backend/dist/index.js +101 -91
  23. package/packages/backend/dist/krnl-services.d.ts +84 -7
  24. package/packages/backend/dist/krnl-services.js +40 -12
  25. package/packages/backend/dist/services/index.d.ts +4 -6
  26. package/packages/backend/dist/services/index.js +2 -2
  27. package/packages/backend/dist/srkl/index.js +6 -4
  28. package/packages/backend/dist/storage/index.js +7 -7
  29. package/packages/backend/dist/workspace/index.js +2 -2
  30. package/packages/backend/kloks.manifest.json +47 -45
  31. package/packages/backend/package.json +3 -8
  32. package/packages/client/package.json +1 -1
  33. package/packages/contracts/dist/index.js +5 -10
  34. package/packages/contracts/package.json +1 -1
  35. package/packages/functions/dist/index.d.ts +12 -1
  36. package/packages/functions/dist/index.js +132 -24
  37. package/packages/functions/package.json +1 -1
  38. package/packages/orchestrations/dist/index.d.ts +33 -31
  39. package/packages/orchestrations/dist/index.js +81 -203
  40. package/packages/orchestrations/kloks.manifest.json +10 -2
  41. package/packages/orchestrations/package.json +2 -2
  42. package/packages/services/dist/index.d.ts +51 -1
  43. package/packages/services/dist/index.js +234 -36
  44. package/packages/services/kloks.manifest.json +69 -33
  45. package/packages/services/package.json +1 -1
  46. package/packages/state-graph/dist/{BaseGraph-BvkSYOTw.d.ts → BaseGraph-Bd5F1NMP.d.ts} +1 -1
  47. package/packages/state-graph/dist/{BaseNode-DTcd3K1B.d.ts → BaseNode-DKpGXMy8.d.ts} +6 -0
  48. package/packages/state-graph/dist/{CompatibilityMatrix-Dj-tCWUA.d.ts → CompatibilityMatrix-TiEJ3j3_.d.ts} +1 -1
  49. package/packages/state-graph/dist/domain/index.d.ts +3 -3
  50. package/packages/state-graph/dist/domain/index.js +0 -1
  51. package/packages/state-graph/dist/index.d.ts +40 -8
  52. package/packages/state-graph/dist/index.js +214 -65
  53. package/packages/state-graph/dist/rules/index.d.ts +3 -3
  54. package/packages/state-graph/dist/rules/index.js +0 -1
  55. package/packages/state-graph/dist/spatial/index.d.ts +4 -4
  56. package/packages/state-graph/dist/spatial/index.js +0 -1
  57. package/packages/state-graph/dist/state/index.js +1 -3
  58. package/packages/state-graph/dist/store/index.d.ts +4 -4
  59. package/packages/state-graph/dist/store/index.js +0 -1
  60. package/packages/state-graph/dist/{types-VDoc4FIc.d.ts → types-D5kQSa65.d.ts} +2 -2
  61. package/packages/state-graph/kloks.manifest.json +26 -10
  62. package/packages/state-graph/package.json +2 -8
  63. package/packages/backend/dist/IdempotencyManager-B5MjK871.d.ts +0 -16
  64. package/packages/backend/dist/chunk-25Y7AVTP.js +0 -55
  65. package/packages/backend/dist/chunk-3EPY34R6.js +0 -67
  66. package/packages/backend/dist/chunk-7KNGX522.js +0 -220
  67. package/packages/backend/dist/chunk-FZKBTF34.js +0 -15
  68. package/packages/backend/dist/chunk-QGHDJGYS.js +0 -92
  69. package/packages/backend/dist/chunk-UPFKBBQI.js +0 -138
  70. package/packages/backend/dist/chunk-VQEFULWT.js +0 -88
  71. package/packages/backend/dist/execution/index.d.ts +0 -124
  72. package/packages/backend/dist/execution/index.js +0 -20
  73. package/packages/backend/dist/types-BERZJ93O.d.ts +0 -110
  74. package/packages/state-graph/dist/chunk-3RG5ZIWI.js +0 -10
  75. package/packages/state-graph/dist/chunk-Q5I42UX7.js +0 -0
  76. package/packages/state-graph/dist/chunk-ZTHBPV24.js +0 -267
  77. package/packages/state-graph/dist/execution/index.d.ts +0 -152
  78. package/packages/state-graph/dist/execution/index.js +0 -16
  79. /package/packages/state-graph/dist/{chunk-SHIBCPGQ.js → chunk-EW4ACSZB.js} +0 -0
@@ -13,8 +13,14 @@
13
13
  "export": "StateLifecycleServiceFacade",
14
14
  "facade": "StateLifecycleServiceFacade"
15
15
  },
16
- "modes": ["backend"],
17
- "targets": { "backend": ["BackendFacade.services"] }
16
+ "modes": [
17
+ "backend"
18
+ ],
19
+ "targets": {
20
+ "backend": [
21
+ "BackendFacade.services"
22
+ ]
23
+ }
18
24
  },
19
25
  {
20
26
  "id": "node-graph",
@@ -26,15 +32,25 @@
26
32
  "export": "NodeGraphEngineServiceFacade",
27
33
  "facade": "NodeGraphEngineServiceFacade"
28
34
  },
29
- "ui": {
30
- "package": "@floks/canvas-ui",
31
- "components": ["InfiniteCanvas"]
32
- },
33
- "modes": ["backend", "fullstack"],
35
+ "modes": [
36
+ "backend",
37
+ "fullstack"
38
+ ],
34
39
  "targets": {
35
- "backend": ["BackendFacade.services"],
36
- "frontend": ["App.main-content"]
37
- }
40
+ "backend": [
41
+ "BackendFacade.services"
42
+ ],
43
+ "frontend": [
44
+ "App.main-content"
45
+ ]
46
+ },
47
+ "defaultFrontend": {
48
+ "component": "FrnlEditableNodeGraph",
49
+ "package": "@ultrst-armada/floks/canvas-ui",
50
+ "export": "FrnlEditableNodeGraph",
51
+ "relationship": "recommended"
52
+ },
53
+ "dependencies": []
38
54
  }
39
55
  ]
40
56
  }
@@ -23,11 +23,6 @@
23
23
  "types": "./dist/state/index.d.ts",
24
24
  "default": "./dist/state/index.js"
25
25
  },
26
- "./execution": {
27
- "import": "./dist/execution/index.js",
28
- "types": "./dist/execution/index.d.ts",
29
- "default": "./dist/execution/index.js"
30
- },
31
26
  "./domain": {
32
27
  "import": "./dist/domain/index.js",
33
28
  "types": "./dist/domain/index.d.ts",
@@ -50,13 +45,12 @@
50
45
  }
51
46
  },
52
47
  "scripts": {
53
- "build": "tsup src/index.ts src/state/index.ts src/execution/index.ts src/domain/index.ts src/rules/index.ts src/spatial/index.ts src/store/index.ts --format esm --dts --clean --external zustand --external bullmq --external react --external ws",
48
+ "build": "tsup src/index.ts src/state/index.ts src/domain/index.ts src/rules/index.ts src/spatial/index.ts src/store/index.ts --format esm --dts --clean --external zustand --external react --external ws",
54
49
  "typecheck": "tsc --noEmit",
55
50
  "clean": "rm -rf dist"
56
51
  },
57
52
  "dependencies": {
58
53
  "@kloks/functions": "workspace:*",
59
- "bullmq": "^6.3.8",
60
54
  "zustand": "^5.0.15"
61
55
  },
62
56
  "peerDependencies": {
@@ -68,6 +62,6 @@
68
62
  }
69
63
  },
70
64
  "devDependencies": {
71
- "@ultrst-armada/krnl": "^1.0.2"
65
+ "@ultrst-armada/krnl": "^1.0.3"
72
66
  }
73
67
  }
@@ -1,16 +0,0 @@
1
- /**
2
- * @file IdempotencyManager.ts
3
- * @description In-flight mutation deduplication, concurrent attachment, and completed result caching.
4
- */
5
- declare class IdempotencyManager {
6
- private inFlight;
7
- private completedCache;
8
- private ttlMs;
9
- constructor(ttlMs?: number);
10
- executeIdempotent<T>(idempotencyKey: string, operation: () => Promise<T>): Promise<T>;
11
- has(idempotencyKey: string): boolean;
12
- prune(): void;
13
- clear(): void;
14
- }
15
-
16
- export { IdempotencyManager as I };
@@ -1,55 +0,0 @@
1
- // src/auth/SessionManager.ts
2
- var SessionManager = class {
3
- ttl;
4
- constructor(ttlMs = 864e5) {
5
- this.ttl = ttlMs;
6
- }
7
- generateToken(userId) {
8
- return `sess::${userId}::${Date.now()}::${Math.random().toString(36).substring(2, 9)}`;
9
- }
10
- createSession(userId, role) {
11
- return {
12
- token: this.generateToken(userId),
13
- userId,
14
- role,
15
- expiresAt: Date.now() + this.ttl
16
- };
17
- }
18
- isValid(session) {
19
- return Date.now() < session.expiresAt;
20
- }
21
- };
22
-
23
- // src/auth/RateLimiter.ts
24
- var RateLimiter = class {
25
- attempts = /* @__PURE__ */ new Map();
26
- windowMs;
27
- maxUser;
28
- maxAdmin;
29
- constructor(windowMs = 9e5, maxUser = 5, maxAdmin = 3) {
30
- this.windowMs = windowMs;
31
- this.maxUser = maxUser;
32
- this.maxAdmin = maxAdmin;
33
- }
34
- check(identifier, isAdminAttempt = false) {
35
- const now = Date.now();
36
- let record = this.attempts.get(identifier);
37
- if (!record || now - record.windowStart > this.windowMs) {
38
- record = { count: 0, windowStart: now };
39
- this.attempts.set(identifier, record);
40
- }
41
- record.count++;
42
- const limit = isAdminAttempt ? this.maxAdmin : this.maxUser;
43
- if (record.count > limit) {
44
- throw new Error("Too many requests. Please try again later.");
45
- }
46
- }
47
- reset(identifier) {
48
- this.attempts.delete(identifier);
49
- }
50
- };
51
-
52
- export {
53
- SessionManager,
54
- RateLimiter
55
- };
@@ -1,67 +0,0 @@
1
- // src/connectivity/IdempotencyManager.ts
2
- var IdempotencyManager = class {
3
- inFlight = /* @__PURE__ */ new Map();
4
- completedCache = /* @__PURE__ */ new Map();
5
- ttlMs;
6
- constructor(ttlMs = 6e4) {
7
- this.ttlMs = ttlMs;
8
- }
9
- async executeIdempotent(idempotencyKey, operation) {
10
- const cached = this.completedCache.get(idempotencyKey);
11
- if (cached) {
12
- if (Date.now() - cached.timestamp < this.ttlMs) {
13
- if (cached.status === "completed") {
14
- return cached.result;
15
- }
16
- throw new Error(cached.error || "[IdempotencyManager] Previous execution failed.");
17
- } else {
18
- this.completedCache.delete(idempotencyKey);
19
- }
20
- }
21
- const existingFlight = this.inFlight.get(idempotencyKey);
22
- if (existingFlight) {
23
- return await existingFlight;
24
- }
25
- const executionPromise = (async () => {
26
- try {
27
- const result = await operation();
28
- this.completedCache.set(idempotencyKey, {
29
- status: "completed",
30
- result,
31
- timestamp: Date.now()
32
- });
33
- return result;
34
- } catch (err) {
35
- this.completedCache.set(idempotencyKey, {
36
- status: "failed",
37
- error: err?.message || String(err),
38
- timestamp: Date.now()
39
- });
40
- throw err;
41
- } finally {
42
- this.inFlight.delete(idempotencyKey);
43
- }
44
- })();
45
- this.inFlight.set(idempotencyKey, executionPromise);
46
- return await executionPromise;
47
- }
48
- has(idempotencyKey) {
49
- return this.inFlight.has(idempotencyKey) || this.completedCache.has(idempotencyKey);
50
- }
51
- prune() {
52
- const now = Date.now();
53
- for (const [key, entry] of this.completedCache.entries()) {
54
- if (now - entry.timestamp > this.ttlMs) {
55
- this.completedCache.delete(key);
56
- }
57
- }
58
- }
59
- clear() {
60
- this.inFlight.clear();
61
- this.completedCache.clear();
62
- }
63
- };
64
-
65
- export {
66
- IdempotencyManager
67
- };
@@ -1,220 +0,0 @@
1
- // ../../node_modules/.pnpm/@ultrst-armada+krnl@1.0.2/node_modules/@ultrst-armada/krnl/packages/core/dist/index.js
2
- var ServiceStateStore = class {
3
- state;
4
- listeners = /* @__PURE__ */ new Set();
5
- constructor(initialState) {
6
- this.state = { ...initialState };
7
- }
8
- getState() {
9
- return Object.freeze({ ...this.state });
10
- }
11
- setState(mutation) {
12
- this.state = { ...this.state, ...mutation };
13
- const snapshot = this.getState();
14
- for (const listener of this.listeners) {
15
- listener(snapshot, mutation);
16
- }
17
- }
18
- subscribe(listener) {
19
- this.listeners.add(listener);
20
- return () => {
21
- this.listeners.delete(listener);
22
- };
23
- }
24
- reset(newState) {
25
- this.state = { ...newState || {} };
26
- }
27
- };
28
- var ServiceEventBus = class {
29
- handlers = /* @__PURE__ */ new Map();
30
- on(event, handler) {
31
- if (!this.handlers.has(event)) {
32
- this.handlers.set(event, /* @__PURE__ */ new Set());
33
- }
34
- const set = this.handlers.get(event);
35
- set.add(handler);
36
- return () => {
37
- set.delete(handler);
38
- };
39
- }
40
- emit(event, payload) {
41
- const set = this.handlers.get(event);
42
- if (!set) return;
43
- for (const handler of Array.from(set)) {
44
- try {
45
- handler(payload);
46
- } catch (err) {
47
- console.error(`[ServiceEventBus] Handler error for '${event}':`, err);
48
- }
49
- }
50
- }
51
- clear() {
52
- this.handlers.clear();
53
- }
54
- };
55
- var LifecycleManager = class {
56
- status = "uninitialized";
57
- getStatus() {
58
- return this.status;
59
- }
60
- setStatus(next) {
61
- this.status = next;
62
- }
63
- assertRunning(serviceName) {
64
- if (this.status !== "running") {
65
- throw new Error(`[Service:${serviceName}] Cannot invoke operation while status is '${this.status}' (expected 'running').`);
66
- }
67
- }
68
- };
69
- var ServiceInstance = class {
70
- constructor(definition) {
71
- this.definition = definition;
72
- this.id = definition.id;
73
- this.name = definition.name;
74
- this.version = definition.version;
75
- this.lifecycle = new LifecycleManager();
76
- this.eventBus = new ServiceEventBus();
77
- if (definition.state?.initial) {
78
- this.stateStore = new ServiceStateStore(definition.state.initial);
79
- }
80
- }
81
- definition;
82
- id;
83
- name;
84
- version;
85
- stateStore;
86
- eventBus;
87
- lifecycle;
88
- getDefinition() {
89
- return this.definition;
90
- }
91
- async start() {
92
- this.lifecycle.setStatus("starting");
93
- if (this.definition.lifecycle?.onInit) {
94
- await this.definition.lifecycle.onInit();
95
- }
96
- if (this.definition.lifecycle?.onStart) {
97
- await this.definition.lifecycle.onStart();
98
- }
99
- this.lifecycle.setStatus("running");
100
- }
101
- async stop() {
102
- this.lifecycle.setStatus("stopping");
103
- if (this.definition.lifecycle?.onStop) {
104
- await this.definition.lifecycle.onStop();
105
- }
106
- if (this.definition.lifecycle?.onDispose) {
107
- await this.definition.lifecycle.onDispose();
108
- }
109
- this.lifecycle.setStatus("stopped");
110
- }
111
- async call(op, input, ctx = {}) {
112
- this.lifecycle.assertRunning(this.name);
113
- const operation = this.definition.operations[op];
114
- if (!operation) {
115
- throw new Error(`[Service:${this.name}] Operation '${op}' not found.`);
116
- }
117
- return await operation.handler(input, ctx);
118
- }
119
- getState() {
120
- if (!this.stateStore) {
121
- return Object.freeze({});
122
- }
123
- return this.stateStore.getState();
124
- }
125
- setState(mutation) {
126
- if (!this.stateStore) {
127
- this.stateStore = new ServiceStateStore(mutation);
128
- return;
129
- }
130
- this.stateStore.setState(mutation);
131
- }
132
- on(event, handler) {
133
- return this.eventBus.on(event, handler);
134
- }
135
- emit(event, payload) {
136
- this.eventBus.emit(event, payload);
137
- }
138
- };
139
- var ServiceProxy = class {
140
- constructor(definition, adapter, endpoint) {
141
- this.definition = definition;
142
- this.adapter = adapter;
143
- this.endpoint = endpoint;
144
- this.id = definition.id;
145
- this.name = definition.name;
146
- this.version = definition.version;
147
- this.stateCache = definition.state?.initial || {};
148
- }
149
- definition;
150
- adapter;
151
- endpoint;
152
- id;
153
- name;
154
- version;
155
- stateCache;
156
- eventHandlers = /* @__PURE__ */ new Map();
157
- getDefinition() {
158
- return this.definition;
159
- }
160
- async start() {
161
- }
162
- async stop() {
163
- }
164
- async call(op, input, ctx = {}) {
165
- if (!this.adapter.send) {
166
- throw new Error(`[ServiceProxy:${this.name}] Adapter does not support send().`);
167
- }
168
- const envelope = {
169
- id: `req-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
170
- type: "request",
171
- operation: op,
172
- payload: input,
173
- timestamp: Date.now()
174
- };
175
- const response = await this.adapter.send(this.endpoint, envelope);
176
- if (response.error) {
177
- throw new Error(`[ServiceProxy:${this.name}] Remote error: ${response.error}`);
178
- }
179
- return response.payload;
180
- }
181
- getState() {
182
- return Object.freeze({ ...this.stateCache });
183
- }
184
- setState(mutation) {
185
- this.stateCache = { ...this.stateCache, ...mutation };
186
- }
187
- on(event, handler) {
188
- if (!this.eventHandlers.has(event)) {
189
- this.eventHandlers.set(event, /* @__PURE__ */ new Set());
190
- }
191
- const handlers = this.eventHandlers.get(event);
192
- handlers.add(handler);
193
- return () => {
194
- handlers.delete(handler);
195
- };
196
- }
197
- emit(event, payload) {
198
- const handlers = this.eventHandlers.get(event);
199
- if (handlers) {
200
- for (const handler of Array.from(handlers)) {
201
- handler(payload);
202
- }
203
- }
204
- }
205
- };
206
- function createServiceDefinition(definition) {
207
- return definition;
208
- }
209
- function createService(definition) {
210
- return new ServiceInstance(definition);
211
- }
212
- function createServiceProxy(definition, adapter, endpoint) {
213
- return new ServiceProxy(definition, adapter, endpoint);
214
- }
215
-
216
- export {
217
- createServiceDefinition,
218
- createService,
219
- createServiceProxy
220
- };
@@ -1,15 +0,0 @@
1
- // src/workspace/WorkspaceCanonical.ts
2
- function formatCanonicalWorkspaceFolderName(appName, userName, workspaceName) {
3
- const safeApp = appName.replace(/[^a-zA-Z0-9]/g, "_").toLowerCase();
4
- const safeUser = userName.replace(/[^a-zA-Z0-9]/g, "_").toLowerCase();
5
- const safeWs = workspaceName.replace(/[^a-zA-Z0-9]/g, "_").toLowerCase();
6
- return `ultrst_${safeApp}_${safeUser}_${safeWs}`;
7
- }
8
- function sanitizeWorkspaceName(name) {
9
- return name.replace(/[^a-zA-Z0-9-_\s]/g, "").trim();
10
- }
11
-
12
- export {
13
- formatCanonicalWorkspaceFolderName,
14
- sanitizeWorkspaceName
15
- };
@@ -1,92 +0,0 @@
1
- import {
2
- IdempotencyManager
3
- } from "./chunk-3EPY34R6.js";
4
-
5
- // src/execution/BackendFacade.ts
6
- var ExecutableBackendFacade = class {
7
- constructor(name, idempotency) {
8
- this.name = name;
9
- this.idempotency = idempotency || new IdempotencyManager();
10
- }
11
- name;
12
- services = /* @__PURE__ */ new Map();
13
- idempotency;
14
- registerService(service) {
15
- this.services.set(service.name, service);
16
- return this;
17
- }
18
- async executeCommand(command, context) {
19
- const startTime = Date.now();
20
- if (!context || !context.isWorkerContext) {
21
- return {
22
- correlationId: command.correlationId,
23
- status: "FAILED",
24
- error: "[BackendFacade] DIRECT_COMPONENT -> BACKEND_FACADE is strictly FORBIDDEN. Access allowed for WORKER_ONLY.",
25
- executionTimestamp: startTime
26
- };
27
- }
28
- const runCore = async () => {
29
- try {
30
- const parts = command.type.split(".");
31
- if (parts.length < 2) {
32
- throw new Error(
33
- `[BackendFacade] Invalid command type "${command.type}". Expected "service.operation".`
34
- );
35
- }
36
- const [serviceName, operationName] = parts;
37
- const service = this.services.get(serviceName);
38
- if (!service) {
39
- throw new Error(`[BackendFacade] Service "${serviceName}" not registered.`);
40
- }
41
- const data = await service.execute(operationName, command.payload);
42
- return {
43
- correlationId: command.correlationId,
44
- status: "COMPLETED",
45
- data,
46
- executionTimestamp: Date.now()
47
- };
48
- } catch (err) {
49
- return {
50
- correlationId: command.correlationId,
51
- status: "FAILED",
52
- error: err?.message || String(err),
53
- executionTimestamp: Date.now()
54
- };
55
- }
56
- };
57
- if (command.idempotencyKey) {
58
- return await this.idempotency.executeIdempotent(command.idempotencyKey, runCore);
59
- }
60
- return await runCore();
61
- }
62
- };
63
-
64
- // src/execution/WorkerExecutionBoundary.ts
65
- var WorkerExecutionBoundary = class {
66
- constructor(workerId, facade) {
67
- this.workerId = workerId;
68
- this.facade = facade;
69
- }
70
- workerId;
71
- facade;
72
- async processJob(command) {
73
- const context = {
74
- isWorkerContext: true,
75
- workerId: this.workerId,
76
- timestamp: Date.now()
77
- };
78
- return await this.facade.executeCommand(command, context);
79
- }
80
- static assertWorkerContext(context) {
81
- if (!context || !context.isWorkerContext) {
82
- throw new Error(
83
- "[WorkerExecutionBoundary] Violation: DIRECT_COMPONENT -> BACKEND_FACADE is forbidden. Only BullMQ Workers may execute backend commands."
84
- );
85
- }
86
- }
87
- };
88
-
89
- export {
90
- ExecutableBackendFacade,
91
- WorkerExecutionBoundary
92
- };
@@ -1,138 +0,0 @@
1
- // src/connectivity/JobScheduler.ts
2
- var JobScheduler = class {
3
- jobs = /* @__PURE__ */ new Map();
4
- handlers = /* @__PURE__ */ new Map();
5
- sequenceCounters = /* @__PURE__ */ new Map();
6
- activeCount = 0;
7
- maxConcurrency;
8
- paused = false;
9
- constructor(maxConcurrency = 5) {
10
- this.maxConcurrency = maxConcurrency;
11
- }
12
- registerHandler(type, handler) {
13
- this.handlers.set(type, handler);
14
- return this;
15
- }
16
- submit(input) {
17
- const id = input.id || `job-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
18
- const streamKey = input.sequenceKey || "default";
19
- const seq = (this.sequenceCounters.get(streamKey) ?? 0) + 1;
20
- this.sequenceCounters.set(streamKey, seq);
21
- const job = {
22
- id,
23
- type: input.type,
24
- payload: input.payload,
25
- priority: input.priority || "NORMAL",
26
- sequence: seq,
27
- sequenceKey: streamKey,
28
- dependencies: input.dependencies || [],
29
- sessionId: input.sessionId,
30
- correlationId: input.correlationId,
31
- state: "PENDING",
32
- progress: 0,
33
- createdAt: Date.now(),
34
- updatedAt: Date.now()
35
- };
36
- this.jobs.set(id, job);
37
- this.checkAndQueue(job);
38
- this.drainQueue();
39
- return job;
40
- }
41
- checkAndQueue(job) {
42
- if (job.state !== "PENDING") return false;
43
- const depsResolved = (job.dependencies || []).every((depId) => {
44
- const dep = this.jobs.get(depId);
45
- return dep && dep.state === "COMPLETED";
46
- });
47
- if (depsResolved) {
48
- job.state = "QUEUED";
49
- job.updatedAt = Date.now();
50
- return true;
51
- }
52
- return false;
53
- }
54
- priorityWeight(priority) {
55
- switch (priority) {
56
- case "CRITICAL":
57
- return 4;
58
- case "HIGH":
59
- return 3;
60
- case "NORMAL":
61
- return 2;
62
- case "LOW":
63
- return 1;
64
- default:
65
- return 2;
66
- }
67
- }
68
- async drainQueue() {
69
- if (this.paused || this.activeCount >= this.maxConcurrency) return;
70
- const queuedJobs = Array.from(this.jobs.values()).filter((j) => j.state === "QUEUED").sort((a, b) => this.priorityWeight(b.priority) - this.priorityWeight(a.priority) || (a.sequence || 0) - (b.sequence || 0));
71
- for (const job of queuedJobs) {
72
- if (this.activeCount >= this.maxConcurrency) break;
73
- this.executeJob(job);
74
- }
75
- }
76
- async executeJob(job) {
77
- const handler = this.handlers.get(job.type);
78
- if (!handler) {
79
- job.state = "FAILED";
80
- job.error = `[JobScheduler] No registered handler for job type "${job.type}".`;
81
- job.updatedAt = Date.now();
82
- return;
83
- }
84
- this.activeCount++;
85
- job.state = "RUNNING";
86
- job.updatedAt = Date.now();
87
- const progressCallback = (progress) => {
88
- job.progress = Math.min(100, Math.max(0, progress));
89
- job.updatedAt = Date.now();
90
- };
91
- try {
92
- job.result = await handler(job, progressCallback);
93
- job.state = "COMPLETED";
94
- job.progress = 100;
95
- } catch (err) {
96
- job.state = "FAILED";
97
- job.error = err?.message || String(err);
98
- } finally {
99
- job.updatedAt = Date.now();
100
- this.activeCount--;
101
- for (const pendingJob of this.jobs.values()) {
102
- if (pendingJob.dependencies?.includes(job.id)) {
103
- this.checkAndQueue(pendingJob);
104
- }
105
- }
106
- this.drainQueue();
107
- }
108
- }
109
- cancel(jobId) {
110
- const job = this.jobs.get(jobId);
111
- if (!job || job.state === "COMPLETED" || job.state === "FAILED") return false;
112
- job.state = "CANCELLED";
113
- job.updatedAt = Date.now();
114
- return true;
115
- }
116
- pause() {
117
- this.paused = true;
118
- }
119
- resume() {
120
- this.paused = false;
121
- this.drainQueue();
122
- }
123
- status(jobId) {
124
- return this.jobs.get(jobId);
125
- }
126
- getAllJobs() {
127
- return Array.from(this.jobs.values());
128
- }
129
- clear() {
130
- this.jobs.clear();
131
- this.sequenceCounters.clear();
132
- this.activeCount = 0;
133
- }
134
- };
135
-
136
- export {
137
- JobScheduler
138
- };