@taskcast/core 0.1.2 → 0.3.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/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'timeout' | 'cancelled';
1
+ export type TaskStatus = 'pending' | 'assigned' | 'running' | 'paused' | 'blocked' | 'completed' | 'failed' | 'timeout' | 'cancelled';
2
2
  export interface TaskError {
3
3
  code?: string;
4
4
  message: string;
@@ -31,7 +31,7 @@ export interface RetryConfig {
31
31
  }
32
32
  export type SeriesMode = 'keep-all' | 'accumulate' | 'latest';
33
33
  export type Level = 'debug' | 'info' | 'warn' | 'error';
34
- export type PermissionScope = 'task:create' | 'task:manage' | 'event:publish' | 'event:subscribe' | 'event:history' | 'webhook:create' | '*';
34
+ export type PermissionScope = 'task:create' | 'task:manage' | 'event:publish' | 'event:subscribe' | 'event:history' | 'webhook:create' | 'worker:connect' | 'worker:manage' | '*';
35
35
  export interface CleanupRule {
36
36
  name?: string;
37
37
  match?: {
@@ -49,6 +49,45 @@ export interface CleanupRule {
49
49
  seriesMode?: SeriesMode[];
50
50
  };
51
51
  }
52
+ export type AssignMode = 'external' | 'pull' | 'ws-offer' | 'ws-race';
53
+ export type DisconnectPolicy = 'reassign' | 'mark' | 'fail';
54
+ export type WorkerStatus = 'idle' | 'busy' | 'draining' | 'offline';
55
+ export interface TagMatcher {
56
+ all?: string[];
57
+ any?: string[];
58
+ none?: string[];
59
+ }
60
+ export interface WorkerMatchRule {
61
+ taskTypes?: string[];
62
+ tags?: TagMatcher;
63
+ }
64
+ export interface Worker {
65
+ id: string;
66
+ status: WorkerStatus;
67
+ matchRule: WorkerMatchRule;
68
+ capacity: number;
69
+ usedSlots: number;
70
+ weight: number;
71
+ connectionMode: 'pull' | 'websocket';
72
+ connectedAt: number;
73
+ lastHeartbeatAt: number;
74
+ metadata?: Record<string, unknown>;
75
+ }
76
+ export type WorkerAssignmentStatus = 'offered' | 'assigned' | 'running';
77
+ export interface WorkerAssignment {
78
+ taskId: string;
79
+ workerId: string;
80
+ cost: number;
81
+ assignedAt: number;
82
+ status: WorkerAssignmentStatus;
83
+ }
84
+ export interface WorkerAuditEvent {
85
+ id: string;
86
+ workerId: string;
87
+ timestamp: number;
88
+ action: 'connected' | 'disconnected' | 'updated' | 'task_assigned' | 'task_declined' | 'task_reclaimed' | 'draining' | 'heartbeat_timeout' | 'pull_request';
89
+ data?: Record<string, unknown>;
90
+ }
52
91
  export interface Task {
53
92
  id: string;
54
93
  type?: string;
@@ -66,6 +105,11 @@ export interface Task {
66
105
  cleanup?: {
67
106
  rules: CleanupRule[];
68
107
  };
108
+ tags?: string[];
109
+ assignMode?: AssignMode;
110
+ cost?: number;
111
+ assignedWorker?: string;
112
+ disconnectPolicy?: DisconnectPolicy;
69
113
  }
70
114
  export interface TaskEvent {
71
115
  id: string;
@@ -121,12 +165,36 @@ export interface ShortTermStore {
121
165
  getSeriesLatest(taskId: string, seriesId: string): Promise<TaskEvent | null>;
122
166
  setSeriesLatest(taskId: string, seriesId: string, event: TaskEvent): Promise<void>;
123
167
  replaceLastSeriesEvent(taskId: string, seriesId: string, event: TaskEvent): Promise<void>;
168
+ listTasks(filter: TaskFilter): Promise<Task[]>;
169
+ saveWorker(worker: Worker): Promise<void>;
170
+ getWorker(workerId: string): Promise<Worker | null>;
171
+ listWorkers(filter?: WorkerFilter): Promise<Worker[]>;
172
+ deleteWorker(workerId: string): Promise<void>;
173
+ claimTask(taskId: string, workerId: string, cost: number): Promise<boolean>;
174
+ addAssignment(assignment: WorkerAssignment): Promise<void>;
175
+ removeAssignment(taskId: string): Promise<void>;
176
+ getWorkerAssignments(workerId: string): Promise<WorkerAssignment[]>;
177
+ getTaskAssignment(taskId: string): Promise<WorkerAssignment | null>;
124
178
  }
125
179
  export interface LongTermStore {
126
180
  saveTask(task: Task): Promise<void>;
127
181
  getTask(taskId: string): Promise<Task | null>;
128
182
  saveEvent(event: TaskEvent): Promise<void>;
129
183
  getEvents(taskId: string, opts?: EventQueryOptions): Promise<TaskEvent[]>;
184
+ saveWorkerEvent(event: WorkerAuditEvent): Promise<void>;
185
+ getWorkerEvents(workerId: string, opts?: EventQueryOptions): Promise<WorkerAuditEvent[]>;
186
+ }
187
+ export interface TaskFilter {
188
+ status?: TaskStatus[];
189
+ types?: string[];
190
+ tags?: TagMatcher;
191
+ assignMode?: AssignMode[];
192
+ excludeTaskIds?: string[];
193
+ limit?: number;
194
+ }
195
+ export interface WorkerFilter {
196
+ status?: WorkerStatus[];
197
+ connectionMode?: ('pull' | 'websocket')[];
130
198
  }
131
199
  export interface ErrorContext {
132
200
  operation: string;
@@ -140,5 +208,11 @@ export interface TaskcastHooks {
140
208
  onWebhookFailed?(config: WebhookConfig, err: unknown): void;
141
209
  onSSEConnect?(taskId: string, clientId: string): void;
142
210
  onSSEDisconnect?(taskId: string, clientId: string, duration: number): void;
211
+ onTaskCreated?(task: Task): void;
212
+ onTaskTransitioned?(task: Task, from: TaskStatus, to: TaskStatus): void;
213
+ onWorkerConnected?(worker: Worker): void;
214
+ onWorkerDisconnected?(worker: Worker, reason: string): void;
215
+ onTaskAssigned?(task: Task, worker: Worker): void;
216
+ onTaskDeclined?(task: Task, worker: Worker, blacklisted: boolean): void;
143
217
  }
144
218
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { Task, Worker, WorkerFilter, WorkerAssignment, BroadcastProvider, ShortTermStore, LongTermStore, TaskcastHooks, AssignMode, DisconnectPolicy, WorkerMatchRule } from './types.js';
2
+ import type { TaskEngine } from './engine.js';
3
+ export interface WorkerManagerOptions {
4
+ engine: TaskEngine;
5
+ shortTermStore: ShortTermStore;
6
+ broadcast: BroadcastProvider;
7
+ longTermStore?: LongTermStore;
8
+ hooks?: TaskcastHooks;
9
+ defaults?: WorkerManagerDefaults;
10
+ }
11
+ export interface WorkerManagerDefaults {
12
+ assignMode?: AssignMode;
13
+ heartbeatIntervalMs?: number;
14
+ heartbeatTimeoutMs?: number;
15
+ offerTimeoutMs?: number;
16
+ disconnectPolicy?: DisconnectPolicy;
17
+ disconnectGraceMs?: number;
18
+ }
19
+ export interface WorkerRegistration {
20
+ id?: string;
21
+ matchRule: WorkerMatchRule;
22
+ capacity: number;
23
+ weight?: number;
24
+ connectionMode: Worker['connectionMode'];
25
+ metadata?: Record<string, unknown>;
26
+ }
27
+ export interface WorkerUpdate {
28
+ weight?: number;
29
+ capacity?: number;
30
+ matchRule?: WorkerMatchRule;
31
+ status?: 'draining';
32
+ }
33
+ export interface DispatchResult {
34
+ matched: boolean;
35
+ workerId?: string;
36
+ }
37
+ export interface ClaimResult {
38
+ success: boolean;
39
+ reason?: string;
40
+ }
41
+ export interface DeclineOptions {
42
+ blacklist?: boolean;
43
+ }
44
+ export declare class WorkerManager {
45
+ private opts;
46
+ private engine;
47
+ private shortTermStore;
48
+ private longTermStore?;
49
+ private hooks?;
50
+ constructor(opts: WorkerManagerOptions);
51
+ get heartbeatIntervalMs(): number;
52
+ private emitTaskAudit;
53
+ private emitWorkerAudit;
54
+ registerWorker(config: WorkerRegistration): Promise<Worker>;
55
+ unregisterWorker(workerId: string): Promise<void>;
56
+ updateWorker(workerId: string, update: WorkerUpdate): Promise<Worker | null>;
57
+ heartbeat(workerId: string): Promise<void>;
58
+ getWorker(workerId: string): Promise<Worker | null>;
59
+ listWorkers(filter?: WorkerFilter): Promise<Worker[]>;
60
+ dispatchTask(taskId: string): Promise<DispatchResult>;
61
+ claimTask(taskId: string, workerId: string): Promise<ClaimResult>;
62
+ declineTask(taskId: string, workerId: string, opts?: DeclineOptions): Promise<void>;
63
+ getWorkerTasks(workerId: string): Promise<WorkerAssignment[]>;
64
+ waitForTask(workerId: string, signal?: AbortSignal): Promise<Task>;
65
+ notifyNewTask(taskId: string): Promise<void>;
66
+ }
67
+ //# sourceMappingURL=worker-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-manager.d.ts","sourceRoot":"","sources":["../src/worker-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,312 @@
1
+ import { ulid } from 'ulidx';
2
+ import { matchesWorkerRule } from './worker-matching.js';
3
+ // ─── WorkerManager ──────────────────────────────────────────────────────────
4
+ export class WorkerManager {
5
+ opts;
6
+ engine;
7
+ shortTermStore;
8
+ longTermStore;
9
+ hooks;
10
+ constructor(opts) {
11
+ this.opts = opts;
12
+ this.engine = opts.engine;
13
+ this.shortTermStore = opts.shortTermStore;
14
+ if (opts.longTermStore)
15
+ this.longTermStore = opts.longTermStore;
16
+ if (opts.hooks)
17
+ this.hooks = opts.hooks;
18
+ }
19
+ get heartbeatIntervalMs() {
20
+ return this.opts.defaults?.heartbeatIntervalMs ?? 30_000;
21
+ }
22
+ // ─── Audit Helpers ──────────────────────────────────────────────────────
23
+ async emitTaskAudit(taskId, action, extra) {
24
+ try {
25
+ await this.opts.engine.publishEvent(taskId, {
26
+ type: 'taskcast:audit',
27
+ level: 'info',
28
+ data: { action, ...extra },
29
+ });
30
+ }
31
+ catch {
32
+ // Task may be in terminal state or not found; audit is best-effort
33
+ }
34
+ }
35
+ emitWorkerAudit(action, workerId, data) {
36
+ if (!this.opts.longTermStore)
37
+ return;
38
+ const event = {
39
+ id: ulid(),
40
+ workerId,
41
+ timestamp: Date.now(),
42
+ action,
43
+ ...(data !== undefined && { data }),
44
+ };
45
+ this.opts.longTermStore.saveWorkerEvent(event).catch(() => { });
46
+ }
47
+ // ─── Worker Registration & Lifecycle ────────────────────────────────────
48
+ async registerWorker(config) {
49
+ const now = Date.now();
50
+ const worker = {
51
+ id: config.id ?? ulid(),
52
+ status: 'idle',
53
+ matchRule: config.matchRule,
54
+ capacity: config.capacity,
55
+ usedSlots: 0,
56
+ weight: config.weight ?? 50,
57
+ connectionMode: config.connectionMode,
58
+ connectedAt: now,
59
+ lastHeartbeatAt: now,
60
+ ...(config.metadata !== undefined && { metadata: config.metadata }),
61
+ };
62
+ await this.shortTermStore.saveWorker(worker);
63
+ this.emitWorkerAudit('connected', worker.id);
64
+ this.hooks?.onWorkerConnected?.(worker);
65
+ return worker;
66
+ }
67
+ async unregisterWorker(workerId) {
68
+ const worker = await this.shortTermStore.getWorker(workerId);
69
+ await this.shortTermStore.deleteWorker(workerId);
70
+ if (worker) {
71
+ this.emitWorkerAudit('disconnected', workerId, { reason: 'unregistered' });
72
+ this.hooks?.onWorkerDisconnected?.(worker, 'unregistered');
73
+ }
74
+ }
75
+ async updateWorker(workerId, update) {
76
+ const worker = await this.shortTermStore.getWorker(workerId);
77
+ if (!worker)
78
+ return null;
79
+ if (update.weight !== undefined)
80
+ worker.weight = update.weight;
81
+ if (update.capacity !== undefined)
82
+ worker.capacity = update.capacity;
83
+ if (update.matchRule !== undefined)
84
+ worker.matchRule = update.matchRule;
85
+ if (update.status !== undefined)
86
+ worker.status = update.status;
87
+ await this.shortTermStore.saveWorker(worker);
88
+ return worker;
89
+ }
90
+ async heartbeat(workerId) {
91
+ const worker = await this.shortTermStore.getWorker(workerId);
92
+ if (!worker)
93
+ return;
94
+ worker.lastHeartbeatAt = Date.now();
95
+ await this.shortTermStore.saveWorker(worker);
96
+ }
97
+ async getWorker(workerId) {
98
+ return this.shortTermStore.getWorker(workerId);
99
+ }
100
+ async listWorkers(filter) {
101
+ return this.shortTermStore.listWorkers(filter);
102
+ }
103
+ // ─── Task Dispatch ─────────────────────────────────────────────────────
104
+ async dispatchTask(taskId) {
105
+ const task = await this.engine.getTask(taskId);
106
+ if (!task || task.status !== 'pending') {
107
+ return { matched: false };
108
+ }
109
+ const blacklist = task.metadata?._blacklistedWorkers ?? [];
110
+ const workers = await this.shortTermStore.listWorkers({ status: ['idle', 'busy'] });
111
+ const taskCost = task.cost ?? 1;
112
+ const candidates = workers.filter((w) => {
113
+ if (blacklist.includes(w.id))
114
+ return false;
115
+ if (w.usedSlots + taskCost > w.capacity)
116
+ return false;
117
+ if (!matchesWorkerRule(task, w.matchRule))
118
+ return false;
119
+ return true;
120
+ });
121
+ if (candidates.length === 0) {
122
+ return { matched: false };
123
+ }
124
+ // Sort: weight desc → available slots desc → connectedAt asc
125
+ candidates.sort((a, b) => {
126
+ if (b.weight !== a.weight)
127
+ return b.weight - a.weight;
128
+ const aAvailable = a.capacity - a.usedSlots;
129
+ const bAvailable = b.capacity - b.usedSlots;
130
+ if (bAvailable !== aAvailable)
131
+ return bAvailable - aAvailable;
132
+ return a.connectedAt - b.connectedAt;
133
+ });
134
+ return { matched: true, workerId: candidates[0].id };
135
+ }
136
+ // ─── Task Claim ────────────────────────────────────────────────────────
137
+ async claimTask(taskId, workerId) {
138
+ const task = await this.engine.getTask(taskId);
139
+ if (!task) {
140
+ return { success: false, reason: 'Task not found' };
141
+ }
142
+ if (task.status !== 'pending') {
143
+ return { success: false, reason: `Task is not pending (status: ${task.status})` };
144
+ }
145
+ const cost = task.cost ?? 1;
146
+ const claimed = await this.shortTermStore.claimTask(taskId, workerId, cost);
147
+ if (!claimed) {
148
+ return { success: false, reason: 'Claim failed (concurrent modification)' };
149
+ }
150
+ // claimTask atomically sets status to 'assigned' and assignedWorker on the
151
+ // store. Re-read to get the authoritative state, then persist to longTermStore.
152
+ const updatedTask = (await this.shortTermStore.getTask(taskId));
153
+ if (this.longTermStore)
154
+ await this.longTermStore.saveTask(updatedTask);
155
+ // Emit audit events for the claim
156
+ this.emitWorkerAudit('task_assigned', workerId, { taskId });
157
+ await this.emitTaskAudit(taskId, 'assigned', { workerId });
158
+ // Create assignment record
159
+ const assignment = {
160
+ taskId,
161
+ workerId,
162
+ cost,
163
+ assignedAt: Date.now(),
164
+ status: 'assigned',
165
+ };
166
+ await this.shortTermStore.addAssignment(assignment);
167
+ // Update worker status (usedSlots already updated by claimTask)
168
+ const worker = await this.shortTermStore.getWorker(workerId);
169
+ if (worker) {
170
+ worker.status = worker.usedSlots >= worker.capacity ? 'busy' : 'idle';
171
+ await this.shortTermStore.saveWorker(worker);
172
+ this.hooks?.onTaskAssigned?.(updatedTask, worker);
173
+ }
174
+ return { success: true };
175
+ }
176
+ // ─── Task Decline ──────────────────────────────────────────────────────
177
+ async declineTask(taskId, workerId, opts) {
178
+ const assignment = await this.shortTermStore.getTaskAssignment(taskId);
179
+ if (!assignment || assignment.workerId !== workerId)
180
+ return;
181
+ // Remove assignment
182
+ await this.shortTermStore.removeAssignment(taskId);
183
+ // Restore worker capacity
184
+ const worker = await this.shortTermStore.getWorker(workerId);
185
+ if (worker) {
186
+ worker.usedSlots = Math.max(0, worker.usedSlots - assignment.cost);
187
+ worker.status = 'idle';
188
+ await this.shortTermStore.saveWorker(worker);
189
+ }
190
+ // Transition task back to pending
191
+ await this.engine.transitionTask(taskId, 'pending');
192
+ // Emit audit events for the decline
193
+ const blacklisted = opts?.blacklist ?? false;
194
+ this.emitWorkerAudit('task_declined', workerId, { taskId });
195
+ await this.emitTaskAudit(taskId, 'declined', { workerId, blacklisted });
196
+ // Clear assignedWorker
197
+ const task = await this.engine.getTask(taskId);
198
+ if (task) {
199
+ delete task.assignedWorker;
200
+ // Add to blacklist if requested
201
+ if (opts?.blacklist) {
202
+ const metadata = task.metadata ?? {};
203
+ const existing = metadata._blacklistedWorkers ?? [];
204
+ metadata._blacklistedWorkers = [...existing, workerId];
205
+ task.metadata = metadata;
206
+ }
207
+ await this.shortTermStore.saveTask(task);
208
+ if (this.longTermStore)
209
+ await this.longTermStore.saveTask(task);
210
+ if (worker) {
211
+ this.hooks?.onTaskDeclined?.(task, worker, blacklisted);
212
+ }
213
+ }
214
+ }
215
+ // ─── Worker Tasks ──────────────────────────────────────────────────────
216
+ async getWorkerTasks(workerId) {
217
+ return this.shortTermStore.getWorkerAssignments(workerId);
218
+ }
219
+ // ─── Pull Mode (Long-Poll) ─────────────────────────────────────────────
220
+ async waitForTask(workerId, signal) {
221
+ const worker = await this.shortTermStore.getWorker(workerId);
222
+ if (!worker)
223
+ throw new Error(`Worker not found: ${workerId}`);
224
+ // Check if already aborted
225
+ if (signal?.aborted) {
226
+ throw new Error('aborted');
227
+ }
228
+ // Check existing pending pull tasks
229
+ const pendingTasks = await this.shortTermStore.listTasks({ status: ['pending'], assignMode: ['pull'] });
230
+ const blacklist = new Set();
231
+ for (const task of pendingTasks) {
232
+ const taskBlacklist = task.metadata?._blacklistedWorkers ?? [];
233
+ if (taskBlacklist.includes(workerId))
234
+ continue;
235
+ if (!matchesWorkerRule(task, worker.matchRule))
236
+ continue;
237
+ const taskCost = task.cost ?? 1;
238
+ if (worker.usedSlots + taskCost > worker.capacity)
239
+ continue;
240
+ const result = await this.claimTask(task.id, workerId);
241
+ if (result.success) {
242
+ this.emitWorkerAudit('pull_request', workerId, { matched: true, taskId: task.id });
243
+ const claimed = await this.engine.getTask(task.id);
244
+ return claimed;
245
+ }
246
+ }
247
+ // Wait for a new task notification via broadcast
248
+ return new Promise((resolve, reject) => {
249
+ let unsubscribe;
250
+ const cleanup = () => {
251
+ unsubscribe?.();
252
+ signal?.removeEventListener('abort', onAbort);
253
+ };
254
+ const onAbort = () => {
255
+ cleanup();
256
+ this.emitWorkerAudit('pull_request', workerId, { matched: false });
257
+ reject(new Error('aborted'));
258
+ };
259
+ if (signal) {
260
+ signal.addEventListener('abort', onAbort);
261
+ }
262
+ unsubscribe = this.opts.broadcast.subscribe('taskcast:worker:new-task', async (event) => {
263
+ const taskId = event.data;
264
+ try {
265
+ // Re-fetch the worker to get current state
266
+ const currentWorker = await this.shortTermStore.getWorker(workerId);
267
+ if (!currentWorker) {
268
+ cleanup();
269
+ reject(new Error(`Worker not found: ${workerId}`));
270
+ return;
271
+ }
272
+ const task = await this.engine.getTask(taskId);
273
+ if (!task || task.status !== 'pending')
274
+ return;
275
+ if (task.assignMode !== 'pull')
276
+ return;
277
+ const taskBlacklist = task.metadata?._blacklistedWorkers ?? [];
278
+ if (taskBlacklist.includes(workerId))
279
+ return;
280
+ if (!matchesWorkerRule(task, currentWorker.matchRule))
281
+ return;
282
+ const taskCost = task.cost ?? 1;
283
+ if (currentWorker.usedSlots + taskCost > currentWorker.capacity)
284
+ return;
285
+ const result = await this.claimTask(taskId, workerId);
286
+ if (result.success) {
287
+ cleanup();
288
+ this.emitWorkerAudit('pull_request', workerId, { matched: true, taskId });
289
+ const claimed = await this.engine.getTask(taskId);
290
+ resolve(claimed);
291
+ }
292
+ }
293
+ catch {
294
+ // Ignore errors from individual task checks
295
+ }
296
+ });
297
+ });
298
+ }
299
+ async notifyNewTask(taskId) {
300
+ const event = {
301
+ id: ulid(),
302
+ taskId: 'system',
303
+ index: 0,
304
+ timestamp: Date.now(),
305
+ type: 'taskcast:worker:new-task',
306
+ level: 'info',
307
+ data: taskId,
308
+ };
309
+ await this.opts.broadcast.publish('taskcast:worker:new-task', event);
310
+ }
311
+ }
312
+ //# sourceMappingURL=worker-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-manager.js","sourceRoot":"","sources":["../src/worker-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { Task, TagMatcher, WorkerMatchRule } from './types.js';
2
+ /**
3
+ * Checks if a set of task tags matches a TagMatcher.
4
+ *
5
+ * - `all`: every tag in `all` must exist in taskTags
6
+ * - `any`: at least one tag in `any` must exist in taskTags
7
+ * - `none`: none of the tags in `none` may exist in taskTags
8
+ * - Empty/undefined matcher matches everything
9
+ * - Undefined taskTags treated as empty array
10
+ * - Empty arrays in matcher fields are vacuous true
11
+ */
12
+ export declare function matchesTag(taskTags: string[] | undefined, matcher: TagMatcher): boolean;
13
+ /**
14
+ * Checks if a task matches a WorkerMatchRule.
15
+ *
16
+ * - If rule has `taskTypes`: task.type must match using wildcard matching
17
+ * - If rule has `tags`: use matchesTag
18
+ * - Both conditions are AND'd
19
+ * - Empty/no rule matches everything
20
+ * - Task with no `type` does not match if rule has `taskTypes`
21
+ */
22
+ export declare function matchesWorkerRule(task: Task, rule: WorkerMatchRule): boolean;
23
+ //# sourceMappingURL=worker-matching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-matching.d.ts","sourceRoot":"","sources":["../src/worker-matching.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAGnE;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAgBvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAW5E"}
@@ -0,0 +1,50 @@
1
+ import { matchesType } from './filter.js';
2
+ /**
3
+ * Checks if a set of task tags matches a TagMatcher.
4
+ *
5
+ * - `all`: every tag in `all` must exist in taskTags
6
+ * - `any`: at least one tag in `any` must exist in taskTags
7
+ * - `none`: none of the tags in `none` may exist in taskTags
8
+ * - Empty/undefined matcher matches everything
9
+ * - Undefined taskTags treated as empty array
10
+ * - Empty arrays in matcher fields are vacuous true
11
+ */
12
+ export function matchesTag(taskTags, matcher) {
13
+ const tags = taskTags ?? [];
14
+ if (matcher.all !== undefined && matcher.all.length > 0) {
15
+ if (!matcher.all.every((tag) => tags.includes(tag)))
16
+ return false;
17
+ }
18
+ if (matcher.any !== undefined && matcher.any.length > 0) {
19
+ if (!matcher.any.some((tag) => tags.includes(tag)))
20
+ return false;
21
+ }
22
+ if (matcher.none !== undefined && matcher.none.length > 0) {
23
+ if (matcher.none.some((tag) => tags.includes(tag)))
24
+ return false;
25
+ }
26
+ return true;
27
+ }
28
+ /**
29
+ * Checks if a task matches a WorkerMatchRule.
30
+ *
31
+ * - If rule has `taskTypes`: task.type must match using wildcard matching
32
+ * - If rule has `tags`: use matchesTag
33
+ * - Both conditions are AND'd
34
+ * - Empty/no rule matches everything
35
+ * - Task with no `type` does not match if rule has `taskTypes`
36
+ */
37
+ export function matchesWorkerRule(task, rule) {
38
+ if (rule.taskTypes !== undefined && rule.taskTypes.length > 0) {
39
+ if (task.type === undefined)
40
+ return false;
41
+ if (!matchesType(task.type, rule.taskTypes))
42
+ return false;
43
+ }
44
+ if (rule.tags !== undefined) {
45
+ if (!matchesTag(task.tags, rule.tags))
46
+ return false;
47
+ }
48
+ return true;
49
+ }
50
+ //# sourceMappingURL=worker-matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-matching.js","sourceRoot":"","sources":["../src/worker-matching.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,QAA8B,EAAE,OAAmB;IAC5E,MAAM,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAA;IAE3B,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IACnE,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAClE,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAClE,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU,EAAE,IAAqB;IACjE,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QACzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAA;IAC3D,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;IACrD,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taskcast/core",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "Task engine, state machine, filtering, series merging. Zero HTTP deps.",
5
5
  "repository": {
6
6
  "type": "git",