dabke 0.82.0 → 0.83.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/CHANGELOG.md +23 -0
- package/README.md +6 -3
- package/dist/cpsat/rules/index.d.ts +3 -0
- package/dist/cpsat/rules/index.d.ts.map +1 -1
- package/dist/cpsat/rules/index.js +3 -0
- package/dist/cpsat/rules/index.js.map +1 -1
- package/dist/cpsat/rules/max-days-week.d.ts +44 -0
- package/dist/cpsat/rules/max-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/max-days-week.js +95 -0
- package/dist/cpsat/rules/max-days-week.js.map +1 -0
- package/dist/cpsat/rules/min-days-week.d.ts +34 -0
- package/dist/cpsat/rules/min-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/min-days-week.js +84 -0
- package/dist/cpsat/rules/min-days-week.js.map +1 -0
- package/dist/cpsat/rules/must-assign.d.ts +49 -0
- package/dist/cpsat/rules/must-assign.d.ts.map +1 -0
- package/dist/cpsat/rules/must-assign.js +86 -0
- package/dist/cpsat/rules/must-assign.js.map +1 -0
- package/dist/cpsat/rules/registry.d.ts +4 -1
- package/dist/cpsat/rules/registry.d.ts.map +1 -1
- package/dist/cpsat/rules/registry.js +4 -1
- package/dist/cpsat/rules/registry.js.map +1 -1
- package/dist/cpsat/rules/rules.types.d.ts +3 -0
- package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.d.ts +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/schedule/cost.d.ts +204 -0
- package/dist/schedule/cost.d.ts.map +1 -0
- package/dist/schedule/cost.js +187 -0
- package/dist/schedule/cost.js.map +1 -0
- package/dist/schedule/coverage.d.ts +85 -0
- package/dist/schedule/coverage.d.ts.map +1 -0
- package/dist/schedule/coverage.js +33 -0
- package/dist/schedule/coverage.js.map +1 -0
- package/dist/schedule/definition.d.ts +227 -0
- package/dist/schedule/definition.d.ts.map +1 -0
- package/dist/{schedule.js → schedule/definition.js} +9 -673
- package/dist/schedule/definition.js.map +1 -0
- package/dist/schedule/index.d.ts +67 -0
- package/dist/schedule/index.d.ts.map +1 -0
- package/dist/schedule/index.js +69 -0
- package/dist/schedule/index.js.map +1 -0
- package/dist/schedule/rules.d.ts +353 -0
- package/dist/schedule/rules.d.ts.map +1 -0
- package/dist/schedule/rules.js +352 -0
- package/dist/schedule/rules.js.map +1 -0
- package/dist/schedule/shift-patterns.d.ts +34 -0
- package/dist/schedule/shift-patterns.d.ts.map +1 -0
- package/dist/schedule/shift-patterns.js +41 -0
- package/dist/schedule/shift-patterns.js.map +1 -0
- package/dist/schedule/time-periods.d.ts +69 -0
- package/dist/schedule/time-periods.d.ts.map +1 -0
- package/dist/schedule/time-periods.js +91 -0
- package/dist/schedule/time-periods.js.map +1 -0
- package/package.json +4 -9
- package/src/cpsat/rules/index.ts +3 -0
- package/src/cpsat/rules/max-days-week.ts +143 -0
- package/src/cpsat/rules/min-days-week.ts +120 -0
- package/src/cpsat/rules/must-assign.ts +108 -0
- package/src/cpsat/rules/registry.ts +6 -0
- package/src/cpsat/rules/rules.types.ts +3 -0
- package/src/cpsat/rules/scope.types.ts +1 -1
- package/src/index.ts +8 -3
- package/src/schedule/cost.ts +242 -0
- package/src/schedule/coverage.ts +135 -0
- package/src/schedule/definition.ts +958 -0
- package/src/schedule/index.ts +112 -0
- package/src/schedule/rules.ts +529 -0
- package/src/schedule/shift-patterns.ts +46 -0
- package/src/schedule/time-periods.ts +110 -0
- package/dist/llms.d.ts +0 -2
- package/dist/llms.d.ts.map +0 -1
- package/dist/llms.js +0 -3
- package/dist/llms.js.map +0 -1
- package/dist/schedule.d.ts +0 -917
- package/dist/schedule.d.ts.map +0 -1
- package/dist/schedule.js.map +0 -1
- package/llms.txt +0 -758
- package/src/llms.ts +0 -3
- package/src/schedule.ts +0 -1960
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduling rules: constraints, preferences, and time-off.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Creates a rule entry for use in {@link ScheduleConfig.rules}.
|
|
8
|
+
*
|
|
9
|
+
* Built-in rules use the helpers (`maxHoursPerDay`, `timeOff`, etc.).
|
|
10
|
+
* Custom rules can use `defineRule` to create entries that plug into the
|
|
11
|
+
* same resolution and compilation pipeline.
|
|
12
|
+
*
|
|
13
|
+
* @param name - Rule name. Must match a key in the rule factory registry.
|
|
14
|
+
* @param fields - Rule-specific configuration fields.
|
|
15
|
+
* @param resolve - Optional custom resolver. When omitted, the default
|
|
16
|
+
* resolution applies: `appliesTo` is mapped to `roleIds`/`skillIds`/`memberIds`,
|
|
17
|
+
* `dates` is renamed to `specificDates`, and all other fields pass through.
|
|
18
|
+
*/
|
|
19
|
+
export function defineRule(name, fields, resolve) {
|
|
20
|
+
const { _type: _, _rule: __, ...safeFields } = fields;
|
|
21
|
+
const entry = { _type: "rule", _rule: name, ...safeFields };
|
|
22
|
+
if (resolve) {
|
|
23
|
+
Object.defineProperty(entry, "_resolve", { value: resolve, enumerable: false });
|
|
24
|
+
}
|
|
25
|
+
return entry;
|
|
26
|
+
}
|
|
27
|
+
function makeRule(rule, fields) {
|
|
28
|
+
return defineRule(rule, fields);
|
|
29
|
+
}
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Constraint Rules
|
|
32
|
+
// ============================================================================
|
|
33
|
+
/**
|
|
34
|
+
* Limits hours per day.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* maxHoursPerDay(10)
|
|
39
|
+
* maxHoursPerDay(4, { appliesTo: "student", dayOfWeek: weekdays })
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @category Rules
|
|
43
|
+
*/
|
|
44
|
+
export function maxHoursPerDay(hours, opts) {
|
|
45
|
+
return makeRule("max-hours-day", { hours, ...opts });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Limits hours per scheduling week.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* maxHoursPerWeek(48)
|
|
53
|
+
* maxHoursPerWeek(20, { appliesTo: "student" })
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @category Rules
|
|
57
|
+
*/
|
|
58
|
+
export function maxHoursPerWeek(hours, opts) {
|
|
59
|
+
return makeRule("max-hours-week", { hours, ...opts });
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Minimum hours when assigned on a day.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* minHoursPerDay(4)
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @category Rules
|
|
70
|
+
*/
|
|
71
|
+
export function minHoursPerDay(hours, opts) {
|
|
72
|
+
return makeRule("min-hours-day", { hours, ...opts });
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Minimum hours per scheduling week.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* minHoursPerWeek(20, { priority: "HIGH" })
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @category Rules
|
|
83
|
+
*/
|
|
84
|
+
export function minHoursPerWeek(hours, opts) {
|
|
85
|
+
return makeRule("min-hours-week", { hours, ...opts });
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Limits working days per scheduling week.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* maxDaysPerWeek(5)
|
|
93
|
+
* maxDaysPerWeek(3, { appliesTo: "part-time" })
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* @category Rules
|
|
97
|
+
*/
|
|
98
|
+
export function maxDaysPerWeek(days, opts) {
|
|
99
|
+
return makeRule("max-days-week", { days, ...opts });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Minimum working days per scheduling week.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* minDaysPerWeek(3, { priority: "HIGH" })
|
|
107
|
+
* minDaysPerWeek(5, { appliesTo: "full-time" })
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @category Rules
|
|
111
|
+
*/
|
|
112
|
+
export function minDaysPerWeek(days, opts) {
|
|
113
|
+
return makeRule("min-days-week", { days, ...opts });
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Maximum distinct shifts per day.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* maxShiftsPerDay(1)
|
|
121
|
+
* maxShiftsPerDay(2, { appliesTo: "student", dayOfWeek: weekend })
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @category Rules
|
|
125
|
+
*/
|
|
126
|
+
export function maxShiftsPerDay(shifts, opts) {
|
|
127
|
+
return makeRule("max-shifts-day", { shifts, ...opts });
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Maximum consecutive working days.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* maxConsecutiveDays(5)
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* @category Rules
|
|
138
|
+
*/
|
|
139
|
+
export function maxConsecutiveDays(days, opts) {
|
|
140
|
+
return makeRule("max-consecutive-days", { days, ...opts });
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Once working, continue for at least this many consecutive days.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* minConsecutiveDays(2, { priority: "HIGH" })
|
|
148
|
+
* ```
|
|
149
|
+
*
|
|
150
|
+
* @category Rules
|
|
151
|
+
*/
|
|
152
|
+
export function minConsecutiveDays(days, opts) {
|
|
153
|
+
return makeRule("min-consecutive-days", { days, ...opts });
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Minimum rest hours between shifts.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* minRestBetweenShifts(10)
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @category Rules
|
|
164
|
+
*/
|
|
165
|
+
export function minRestBetweenShifts(hours, opts) {
|
|
166
|
+
return makeRule("min-rest-between-shifts", { hours, ...opts });
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Prefer (`"high"`) or avoid (`"low"`) assigning. Requires `appliesTo`.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* preference("high", { appliesTo: "waiter" })
|
|
174
|
+
* preference("low", { appliesTo: "student", dayOfWeek: weekdays })
|
|
175
|
+
* ```
|
|
176
|
+
*
|
|
177
|
+
* @category Rules
|
|
178
|
+
*/
|
|
179
|
+
export function preference(level, opts) {
|
|
180
|
+
return makeRule("assignment-priority", { preference: level, ...opts });
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Prefer assigning to shifts at a specific location. Requires `appliesTo`.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* preferLocation("terrace", { appliesTo: "alice" })
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @category Rules
|
|
191
|
+
*/
|
|
192
|
+
export function preferLocation(locationId, opts) {
|
|
193
|
+
return makeRule("location-preference", { locationId, ...opts });
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Guarantees that targeted members appear on the schedule each week.
|
|
197
|
+
*
|
|
198
|
+
* @remarks
|
|
199
|
+
* Use for staffing obligations: salaried employees who are paid regardless
|
|
200
|
+
* of whether they work, or contracted staff who must be rostered. The solver
|
|
201
|
+
* ensures each targeted member has at least one assignment per scheduling week.
|
|
202
|
+
*
|
|
203
|
+
* Always a soft constraint (HIGH priority internally). The schedule still
|
|
204
|
+
* generates when a member genuinely cannot be placed (e.g., full week of
|
|
205
|
+
* absences). Violations surface as validation warnings with distinct
|
|
206
|
+
* messaging from {@link minDaysPerWeek}. Priority is not configurable;
|
|
207
|
+
* the rule name communicates the intent.
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```typescript
|
|
211
|
+
* mustAssign({ appliesTo: "diana" })
|
|
212
|
+
* mustAssign({ appliesTo: ["diana", "yavuz"] })
|
|
213
|
+
* ```
|
|
214
|
+
*
|
|
215
|
+
* @category Rules
|
|
216
|
+
*/
|
|
217
|
+
export function mustAssign(opts) {
|
|
218
|
+
return makeRule("must-assign", { ...opts });
|
|
219
|
+
}
|
|
220
|
+
// ============================================================================
|
|
221
|
+
// Special Rules (custom resolvers)
|
|
222
|
+
// ============================================================================
|
|
223
|
+
/**
|
|
224
|
+
* Block assignments during specified periods.
|
|
225
|
+
* Requires at least one time scope (`dayOfWeek`, `dateRange`, `dates`, or `from`/`until`).
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* // Full days off
|
|
230
|
+
* timeOff({ appliesTo: "alice", dateRange: { start: "2024-02-01", end: "2024-02-05" } })
|
|
231
|
+
*
|
|
232
|
+
* // Every weekend off
|
|
233
|
+
* timeOff({ appliesTo: "mauro", dayOfWeek: weekend })
|
|
234
|
+
*
|
|
235
|
+
* // Wednesday afternoons off
|
|
236
|
+
* timeOff({ appliesTo: "student", dayOfWeek: ["wednesday"], from: t(14) })
|
|
237
|
+
* ```
|
|
238
|
+
*
|
|
239
|
+
* @category Rules
|
|
240
|
+
*/
|
|
241
|
+
export function timeOff(opts) {
|
|
242
|
+
const { from, until, ...rest } = opts;
|
|
243
|
+
return defineRule("time-off", { from, until, ...rest }, (ctx) => {
|
|
244
|
+
if (!rest.dayOfWeek && !rest.dateRange && !rest.dates && !rest.recurringPeriods) {
|
|
245
|
+
throw new Error("timeOff() requires at least one time scope (dayOfWeek, dateRange, dates, or recurringPeriods).");
|
|
246
|
+
}
|
|
247
|
+
const { appliesTo, dates, ...passthrough } = rest;
|
|
248
|
+
const entityScope = resolveAppliesTo(appliesTo, ctx.roles, ctx.skills, ctx.memberIds);
|
|
249
|
+
const resolvedDates = dates ? { specificDates: dates } : {};
|
|
250
|
+
const partialDay = {};
|
|
251
|
+
if (from && until) {
|
|
252
|
+
partialDay.startTime = from;
|
|
253
|
+
partialDay.endTime = until;
|
|
254
|
+
}
|
|
255
|
+
else if (from) {
|
|
256
|
+
partialDay.startTime = from;
|
|
257
|
+
partialDay.endTime = { hours: 23, minutes: 59 };
|
|
258
|
+
}
|
|
259
|
+
else if (until) {
|
|
260
|
+
partialDay.startTime = { hours: 0, minutes: 0 };
|
|
261
|
+
partialDay.endTime = until;
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
name: "time-off",
|
|
265
|
+
...passthrough,
|
|
266
|
+
...entityScope,
|
|
267
|
+
...resolvedDates,
|
|
268
|
+
...partialDay,
|
|
269
|
+
};
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Members work the same shifts on days they are both assigned.
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* ```typescript
|
|
277
|
+
* assignTogether(["alice", "bob"])
|
|
278
|
+
* assignTogether(["alice", "bob", "charlie"], { priority: "HIGH" })
|
|
279
|
+
* ```
|
|
280
|
+
*
|
|
281
|
+
* @category Rules
|
|
282
|
+
*/
|
|
283
|
+
export function assignTogether(memberIds, opts) {
|
|
284
|
+
return defineRule("assign-together", { members: memberIds, ...opts }, (ctx) => {
|
|
285
|
+
for (const member of memberIds) {
|
|
286
|
+
if (!ctx.memberIds.has(member)) {
|
|
287
|
+
throw new Error(`assignTogether references unknown member "${member}". ` +
|
|
288
|
+
`Known member IDs: ${[...ctx.memberIds].join(", ")}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
name: "assign-together",
|
|
293
|
+
groupMemberIds: memberIds,
|
|
294
|
+
...opts,
|
|
295
|
+
};
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
// ============================================================================
|
|
299
|
+
// Internal: appliesTo resolution (shared with definition.ts)
|
|
300
|
+
// ============================================================================
|
|
301
|
+
/**
|
|
302
|
+
* Resolves an `appliesTo` value into entity scope fields.
|
|
303
|
+
*
|
|
304
|
+
* Each target string is checked against roles, skills, then member IDs.
|
|
305
|
+
* If all targets resolve to the same namespace, they are combined into one
|
|
306
|
+
* scope field. If they span namespaces, an error is thrown; the caller
|
|
307
|
+
* should use separate rule entries instead.
|
|
308
|
+
*
|
|
309
|
+
* @internal
|
|
310
|
+
*/
|
|
311
|
+
export function resolveAppliesTo(appliesTo, roles, skills, memberIds) {
|
|
312
|
+
if (!appliesTo)
|
|
313
|
+
return {};
|
|
314
|
+
const targets = Array.isArray(appliesTo) ? appliesTo : [appliesTo];
|
|
315
|
+
if (targets.length === 0)
|
|
316
|
+
return {};
|
|
317
|
+
const resolvedRoles = [];
|
|
318
|
+
const resolvedSkills = [];
|
|
319
|
+
const resolvedMembers = [];
|
|
320
|
+
for (const target of targets) {
|
|
321
|
+
if (roles.has(target)) {
|
|
322
|
+
resolvedRoles.push(target);
|
|
323
|
+
}
|
|
324
|
+
else if (skills.has(target)) {
|
|
325
|
+
resolvedSkills.push(target);
|
|
326
|
+
}
|
|
327
|
+
else if (memberIds.has(target)) {
|
|
328
|
+
resolvedMembers.push(target);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
throw new Error(`appliesTo target "${target}" is not a declared role, skill, or member ID.`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// Count how many namespaces were used
|
|
335
|
+
const namespacesUsed = [resolvedRoles, resolvedSkills, resolvedMembers].filter((arr) => arr.length > 0).length;
|
|
336
|
+
if (namespacesUsed > 1) {
|
|
337
|
+
throw new Error(`appliesTo targets span multiple namespaces (roles: [${resolvedRoles.join(", ")}], ` +
|
|
338
|
+
`skills: [${resolvedSkills.join(", ")}], members: [${resolvedMembers.join(", ")}]). ` +
|
|
339
|
+
`Use separate rule entries for each namespace.`);
|
|
340
|
+
}
|
|
341
|
+
if (resolvedRoles.length > 0) {
|
|
342
|
+
return { roleIds: resolvedRoles };
|
|
343
|
+
}
|
|
344
|
+
if (resolvedSkills.length > 0) {
|
|
345
|
+
return { skillIds: resolvedSkills };
|
|
346
|
+
}
|
|
347
|
+
if (resolvedMembers.length > 0) {
|
|
348
|
+
return { memberIds: resolvedMembers };
|
|
349
|
+
}
|
|
350
|
+
return {};
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/schedule/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shift pattern definitions: time slots available for employee assignment.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { TimeOfDay } from "../types.js";
|
|
7
|
+
import type { ShiftPattern } from "../cpsat/types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Define a shift pattern: a time slot available for employee assignment.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* Each pattern repeats daily unless filtered by `dayOfWeek`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* shiftPatterns: [
|
|
17
|
+
* shift("morning", t(11, 30), t(15)),
|
|
18
|
+
* shift("evening", t(17), t(22)),
|
|
19
|
+
*
|
|
20
|
+
* // Role-restricted shift
|
|
21
|
+
* shift("kitchen", t(6), t(14), { roleIds: ["chef", "prep_cook"] }),
|
|
22
|
+
*
|
|
23
|
+
* // Day-restricted shift
|
|
24
|
+
* shift("saturday_short", t(9), t(14), { dayOfWeek: ["saturday"] }),
|
|
25
|
+
*
|
|
26
|
+
* // Location-specific shift
|
|
27
|
+
* shift("terrace_lunch", t(12), t(16), { locationId: "terrace" }),
|
|
28
|
+
* ]
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @category Shift Patterns
|
|
32
|
+
*/
|
|
33
|
+
export declare function shift(id: string, startTime: TimeOfDay, endTime: TimeOfDay, opts?: Pick<ShiftPattern, "roleIds" | "dayOfWeek" | "locationId">): ShiftPattern;
|
|
34
|
+
//# sourceMappingURL=shift-patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shift-patterns.d.ts","sourceRoot":"","sources":["../../src/schedule/shift-patterns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,KAAK,CACnB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,SAAS,EAClB,IAAI,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,WAAW,GAAG,YAAY,CAAC,GAChE,YAAY,CAMd"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shift pattern definitions: time slots available for employee assignment.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Define a shift pattern: a time slot available for employee assignment.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Each pattern repeats daily unless filtered by `dayOfWeek`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* shiftPatterns: [
|
|
15
|
+
* shift("morning", t(11, 30), t(15)),
|
|
16
|
+
* shift("evening", t(17), t(22)),
|
|
17
|
+
*
|
|
18
|
+
* // Role-restricted shift
|
|
19
|
+
* shift("kitchen", t(6), t(14), { roleIds: ["chef", "prep_cook"] }),
|
|
20
|
+
*
|
|
21
|
+
* // Day-restricted shift
|
|
22
|
+
* shift("saturday_short", t(9), t(14), { dayOfWeek: ["saturday"] }),
|
|
23
|
+
*
|
|
24
|
+
* // Location-specific shift
|
|
25
|
+
* shift("terrace_lunch", t(12), t(16), { locationId: "terrace" }),
|
|
26
|
+
* ]
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @category Shift Patterns
|
|
30
|
+
*/
|
|
31
|
+
export function shift(id, startTime, endTime, opts) {
|
|
32
|
+
const pattern = { id, startTime, endTime };
|
|
33
|
+
if (opts?.roleIds)
|
|
34
|
+
pattern.roleIds = opts.roleIds;
|
|
35
|
+
if (opts?.dayOfWeek)
|
|
36
|
+
pattern.dayOfWeek = opts.dayOfWeek;
|
|
37
|
+
if (opts?.locationId)
|
|
38
|
+
pattern.locationId = opts.locationId;
|
|
39
|
+
return pattern;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=shift-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shift-patterns.js","sourceRoot":"","sources":["../../src/schedule/shift-patterns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,KAAK,CACnB,EAAU,EACV,SAAoB,EACpB,OAAkB,EAClB,IAAiE;IAEjE,MAAM,OAAO,GAAiB,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IACzD,IAAI,IAAI,EAAE,OAAO;QAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAClD,IAAI,IAAI,EAAE,SAAS;QAAE,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IACxD,IAAI,IAAI,EAAE,UAAU;QAAE,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IAC3D,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time period primitives: day constants and time constructors.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { TimeOfDay } from "../types.js";
|
|
7
|
+
import type { SemanticTimeVariant, SemanticTimeEntry } from "../cpsat/semantic-time.js";
|
|
8
|
+
/**
|
|
9
|
+
* Creates a {@link TimeOfDay} value.
|
|
10
|
+
*
|
|
11
|
+
* @param hours - Hour component (0-23)
|
|
12
|
+
* @param minutes - Minute component (0-59)
|
|
13
|
+
*
|
|
14
|
+
* @example Hours only
|
|
15
|
+
* ```ts
|
|
16
|
+
* t(9) // { hours: 9, minutes: 0 }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example Hours and minutes
|
|
20
|
+
* ```ts
|
|
21
|
+
* t(17, 30) // { hours: 17, minutes: 30 }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @category Time Periods
|
|
25
|
+
*/
|
|
26
|
+
export declare function t(hours: number, minutes?: number): TimeOfDay;
|
|
27
|
+
/**
|
|
28
|
+
* Monday through Friday.
|
|
29
|
+
*
|
|
30
|
+
* @category Time Periods
|
|
31
|
+
*/
|
|
32
|
+
export declare const weekdays: readonly ["monday", "tuesday", "wednesday", "thursday", "friday"];
|
|
33
|
+
/**
|
|
34
|
+
* Saturday and Sunday.
|
|
35
|
+
*
|
|
36
|
+
* @category Time Periods
|
|
37
|
+
*/
|
|
38
|
+
export declare const weekend: readonly ["saturday", "sunday"];
|
|
39
|
+
/**
|
|
40
|
+
* Define a named semantic time period.
|
|
41
|
+
*
|
|
42
|
+
* @remarks
|
|
43
|
+
* Each entry has `startTime`/`endTime` and optional `dayOfWeek` or `dates`
|
|
44
|
+
* scoping. Entries without scoping are the default.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* times: {
|
|
49
|
+
* // Simple: same times every day
|
|
50
|
+
* lunch: time({ startTime: t(12), endTime: t(15) }),
|
|
51
|
+
*
|
|
52
|
+
* // Variants: different times on weekends
|
|
53
|
+
* dinner: time(
|
|
54
|
+
* { startTime: t(17), endTime: t(21) },
|
|
55
|
+
* { startTime: t(18), endTime: t(22), dayOfWeek: weekend },
|
|
56
|
+
* ),
|
|
57
|
+
*
|
|
58
|
+
* // Point-in-time window (keyholder at opening)
|
|
59
|
+
* opening: time({ startTime: t(8, 30), endTime: t(9) }),
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @privateRemarks
|
|
64
|
+
* Resolution precedence: `dates` > `dayOfWeek` > default.
|
|
65
|
+
*
|
|
66
|
+
* @category Time Periods
|
|
67
|
+
*/
|
|
68
|
+
export declare function time(...entries: [SemanticTimeVariant, ...SemanticTimeVariant[]]): SemanticTimeEntry;
|
|
69
|
+
//# sourceMappingURL=time-periods.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-periods.d.ts","sourceRoot":"","sources":["../../src/schedule/time-periods.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAEV,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,SAAS,CAEvD;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,mEAMoC,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,OAAO,iCAGnB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,IAAI,CAClB,GAAG,OAAO,EAAE,CAAC,mBAAmB,EAAE,GAAG,mBAAmB,EAAE,CAAC,GAC1D,iBAAiB,CAoBnB"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time period primitives: day constants and time constructors.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Creates a {@link TimeOfDay} value.
|
|
8
|
+
*
|
|
9
|
+
* @param hours - Hour component (0-23)
|
|
10
|
+
* @param minutes - Minute component (0-59)
|
|
11
|
+
*
|
|
12
|
+
* @example Hours only
|
|
13
|
+
* ```ts
|
|
14
|
+
* t(9) // { hours: 9, minutes: 0 }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @example Hours and minutes
|
|
18
|
+
* ```ts
|
|
19
|
+
* t(17, 30) // { hours: 17, minutes: 30 }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @category Time Periods
|
|
23
|
+
*/
|
|
24
|
+
export function t(hours, minutes = 0) {
|
|
25
|
+
return { hours, minutes };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Monday through Friday.
|
|
29
|
+
*
|
|
30
|
+
* @category Time Periods
|
|
31
|
+
*/
|
|
32
|
+
export const weekdays = [
|
|
33
|
+
"monday",
|
|
34
|
+
"tuesday",
|
|
35
|
+
"wednesday",
|
|
36
|
+
"thursday",
|
|
37
|
+
"friday",
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Saturday and Sunday.
|
|
41
|
+
*
|
|
42
|
+
* @category Time Periods
|
|
43
|
+
*/
|
|
44
|
+
export const weekend = ["saturday", "sunday"];
|
|
45
|
+
/**
|
|
46
|
+
* Define a named semantic time period.
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* Each entry has `startTime`/`endTime` and optional `dayOfWeek` or `dates`
|
|
50
|
+
* scoping. Entries without scoping are the default.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* times: {
|
|
55
|
+
* // Simple: same times every day
|
|
56
|
+
* lunch: time({ startTime: t(12), endTime: t(15) }),
|
|
57
|
+
*
|
|
58
|
+
* // Variants: different times on weekends
|
|
59
|
+
* dinner: time(
|
|
60
|
+
* { startTime: t(17), endTime: t(21) },
|
|
61
|
+
* { startTime: t(18), endTime: t(22), dayOfWeek: weekend },
|
|
62
|
+
* ),
|
|
63
|
+
*
|
|
64
|
+
* // Point-in-time window (keyholder at opening)
|
|
65
|
+
* opening: time({ startTime: t(8, 30), endTime: t(9) }),
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @privateRemarks
|
|
70
|
+
* Resolution precedence: `dates` > `dayOfWeek` > default.
|
|
71
|
+
*
|
|
72
|
+
* @category Time Periods
|
|
73
|
+
*/
|
|
74
|
+
export function time(...entries) {
|
|
75
|
+
// Validate: at most one default (no dayOfWeek and no dates)
|
|
76
|
+
const defaults = entries.filter((e) => !e.dayOfWeek && !e.dates);
|
|
77
|
+
if (defaults.length > 1) {
|
|
78
|
+
throw new Error("time() accepts at most one default entry (without dayOfWeek or dates). " +
|
|
79
|
+
`Found ${defaults.length} default entries.`);
|
|
80
|
+
}
|
|
81
|
+
// Single entry without scoping: simple SemanticTimeDef
|
|
82
|
+
if (entries.length === 1 && !entries[0].dayOfWeek && !entries[0].dates) {
|
|
83
|
+
return {
|
|
84
|
+
startTime: entries[0].startTime,
|
|
85
|
+
endTime: entries[0].endTime,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Multiple entries or scoped entries: shallow-copy to decouple from caller
|
|
89
|
+
return entries.map((entry) => Object.assign({}, entry));
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=time-periods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-periods.js","sourceRoot":"","sources":["../../src/schedule/time-periods.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,CAAC,CAAC,KAAa,EAAE,OAAO,GAAG,CAAC;IAC1C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ;IACR,SAAS;IACT,WAAW;IACX,UAAU;IACV,QAAQ;CAC+C,CAAC;AAE1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,UAAU,EAAE,QAAQ,CAG3C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,IAAI,CAClB,GAAG,OAAwD;IAE3D,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACjE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,yEAAyE;YACvE,SAAS,QAAQ,CAAC,MAAM,mBAAmB,CAC9C,CAAC;IACJ,CAAC;IAED,uDAAuD;IACvD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;QACvE,OAAO;YACL,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;YAC/B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO;SACF,CAAC;IAC9B,CAAC;IAED,2EAA2E;IAC3E,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AAC1D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dabke",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.83.0",
|
|
4
4
|
"description": "Scheduling library powered by constraint programming (CP-SAT)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"constraint-programming",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
"CHANGELOG.md",
|
|
27
27
|
"dist",
|
|
28
28
|
"LICENSE",
|
|
29
|
-
"llms.txt",
|
|
30
29
|
"README.md",
|
|
31
30
|
"solver",
|
|
32
31
|
"src"
|
|
@@ -40,10 +39,6 @@
|
|
|
40
39
|
"types": "./dist/index.d.ts",
|
|
41
40
|
"default": "./dist/index.js"
|
|
42
41
|
},
|
|
43
|
-
"./llms": {
|
|
44
|
-
"types": "./dist/llms.d.ts",
|
|
45
|
-
"default": "./dist/llms.js"
|
|
46
|
-
},
|
|
47
42
|
"./testing": {
|
|
48
43
|
"types": "./dist/testing/index.d.ts",
|
|
49
44
|
"default": "./dist/testing/index.js"
|
|
@@ -59,14 +54,14 @@
|
|
|
59
54
|
"test:unit:watch": "vitest --watch --project=unit",
|
|
60
55
|
"test:integration": "[ -f .env ] && { set -a; source .env; set +a; } && vitest run --project=integration",
|
|
61
56
|
"test:integration:watch": "[ -f .env ] && { set -a; source .env; set +a; } && vitest --watch --project=integration",
|
|
62
|
-
"generate:
|
|
57
|
+
"generate:reference": "tsx scripts/generate-reference.ts"
|
|
63
58
|
},
|
|
64
59
|
"dependencies": {
|
|
65
60
|
"zod": "^4.3.6"
|
|
66
61
|
},
|
|
67
62
|
"devDependencies": {
|
|
68
|
-
"@types/node": "^
|
|
69
|
-
"commander": "^14.0.
|
|
63
|
+
"@types/node": "^25.0.0",
|
|
64
|
+
"commander": "^14.0.3",
|
|
70
65
|
"typescript": "^5.9.3",
|
|
71
66
|
"vitest": "^4.0.18"
|
|
72
67
|
},
|
package/src/cpsat/rules/index.ts
CHANGED
|
@@ -2,13 +2,16 @@ export { createAssignTogetherRule } from "./assign-together.js";
|
|
|
2
2
|
export { createAssignmentPriorityRule } from "./assignment-priority.js";
|
|
3
3
|
export { createLocationPreferenceRule } from "./location-preference.js";
|
|
4
4
|
export { createMaxConsecutiveDaysRule } from "./max-consecutive-days.js";
|
|
5
|
+
export { createMaxDaysWeekRule } from "./max-days-week.js";
|
|
5
6
|
export { createMaxHoursDayRule } from "./max-hours-day.js";
|
|
6
7
|
export { createMaxHoursWeekRule } from "./max-hours-week.js";
|
|
7
8
|
export { createMaxShiftsDayRule } from "./max-shifts-day.js";
|
|
8
9
|
export { createMinConsecutiveDaysRule } from "./min-consecutive-days.js";
|
|
10
|
+
export { createMinDaysWeekRule } from "./min-days-week.js";
|
|
9
11
|
export { createMinHoursDayRule } from "./min-hours-day.js";
|
|
10
12
|
export { createMinHoursWeekRule } from "./min-hours-week.js";
|
|
11
13
|
export { createMinRestBetweenShiftsRule } from "./min-rest-between-shifts.js";
|
|
14
|
+
export { createMustAssignRule } from "./must-assign.js";
|
|
12
15
|
export { createTimeOffRule } from "./time-off.js";
|
|
13
16
|
export { createMinimizeCostRule } from "./minimize-cost.js";
|
|
14
17
|
export { createDayCostMultiplierRule } from "./day-cost-multiplier.js";
|