@polpo-ai/core 0.15.44 → 0.15.46

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 (94) hide show
  1. package/README.md +11 -2
  2. package/dist/__tests__/guardrail-engine.test.js +41 -1
  3. package/dist/__tests__/guardrail-engine.test.js.map +1 -1
  4. package/dist/__tests__/task-runner-guardrail-events.test.d.ts +2 -0
  5. package/dist/__tests__/task-runner-guardrail-events.test.d.ts.map +1 -0
  6. package/dist/__tests__/task-runner-guardrail-events.test.js +130 -0
  7. package/dist/__tests__/task-runner-guardrail-events.test.js.map +1 -0
  8. package/dist/adapter.d.ts +5 -1
  9. package/dist/adapter.d.ts.map +1 -1
  10. package/dist/events.d.ts +7 -0
  11. package/dist/events.d.ts.map +1 -1
  12. package/dist/guardrails/index.d.ts +1 -1
  13. package/dist/guardrails/index.d.ts.map +1 -1
  14. package/dist/guardrails/index.js +1 -1
  15. package/dist/guardrails/index.js.map +1 -1
  16. package/dist/guardrails/tool-middleware.d.ts +9 -0
  17. package/dist/guardrails/tool-middleware.d.ts.map +1 -1
  18. package/dist/guardrails/tool-middleware.js +31 -1
  19. package/dist/guardrails/tool-middleware.js.map +1 -1
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +2 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/mission-executor.d.ts +8 -2
  25. package/dist/mission-executor.d.ts.map +1 -1
  26. package/dist/mission-executor.js.map +1 -1
  27. package/dist/orchestrator-engine.d.ts +4 -0
  28. package/dist/orchestrator-engine.d.ts.map +1 -1
  29. package/dist/orchestrator-engine.js.map +1 -1
  30. package/dist/scheduling/dispatcher.d.ts +45 -0
  31. package/dist/scheduling/dispatcher.d.ts.map +1 -0
  32. package/dist/scheduling/dispatcher.js +201 -0
  33. package/dist/scheduling/dispatcher.js.map +1 -0
  34. package/dist/scheduling/dispatcher.test.d.ts +2 -0
  35. package/dist/scheduling/dispatcher.test.d.ts.map +1 -0
  36. package/dist/scheduling/dispatcher.test.js +378 -0
  37. package/dist/scheduling/dispatcher.test.js.map +1 -0
  38. package/dist/scheduling/driver.d.ts +15 -0
  39. package/dist/scheduling/driver.d.ts.map +1 -0
  40. package/dist/scheduling/driver.js +2 -0
  41. package/dist/scheduling/driver.js.map +1 -0
  42. package/dist/scheduling/index.d.ts +9 -0
  43. package/dist/scheduling/index.d.ts.map +1 -0
  44. package/dist/scheduling/index.js +8 -0
  45. package/dist/scheduling/index.js.map +1 -0
  46. package/dist/scheduling/occurrence.d.ts +17 -0
  47. package/dist/scheduling/occurrence.d.ts.map +1 -0
  48. package/dist/scheduling/occurrence.js +164 -0
  49. package/dist/scheduling/occurrence.js.map +1 -0
  50. package/dist/scheduling/occurrence.test.d.ts +2 -0
  51. package/dist/scheduling/occurrence.test.d.ts.map +1 -0
  52. package/dist/scheduling/occurrence.test.js +148 -0
  53. package/dist/scheduling/occurrence.test.js.map +1 -0
  54. package/dist/scheduling/state-machine.d.ts +10 -0
  55. package/dist/scheduling/state-machine.d.ts.map +1 -0
  56. package/dist/scheduling/state-machine.js +36 -0
  57. package/dist/scheduling/state-machine.js.map +1 -0
  58. package/dist/scheduling/state-machine.test.d.ts +2 -0
  59. package/dist/scheduling/state-machine.test.d.ts.map +1 -0
  60. package/dist/scheduling/state-machine.test.js +77 -0
  61. package/dist/scheduling/state-machine.test.js.map +1 -0
  62. package/dist/scheduling/store.d.ts +100 -0
  63. package/dist/scheduling/store.d.ts.map +1 -0
  64. package/dist/scheduling/store.js +635 -0
  65. package/dist/scheduling/store.js.map +1 -0
  66. package/dist/scheduling/store.test.d.ts +2 -0
  67. package/dist/scheduling/store.test.d.ts.map +1 -0
  68. package/dist/scheduling/store.test.js +462 -0
  69. package/dist/scheduling/store.test.js.map +1 -0
  70. package/dist/scheduling/types.d.ts +195 -0
  71. package/dist/scheduling/types.d.ts.map +1 -0
  72. package/dist/scheduling/types.js +2 -0
  73. package/dist/scheduling/types.js.map +1 -0
  74. package/dist/scheduling/validation.d.ts +28 -0
  75. package/dist/scheduling/validation.d.ts.map +1 -0
  76. package/dist/scheduling/validation.js +614 -0
  77. package/dist/scheduling/validation.js.map +1 -0
  78. package/dist/scheduling/validation.test.d.ts +2 -0
  79. package/dist/scheduling/validation.test.d.ts.map +1 -0
  80. package/dist/scheduling/validation.test.js +576 -0
  81. package/dist/scheduling/validation.test.js.map +1 -0
  82. package/dist/task-runner.d.ts +1 -0
  83. package/dist/task-runner.d.ts.map +1 -1
  84. package/dist/task-runner.js +38 -0
  85. package/dist/task-runner.js.map +1 -1
  86. package/dist/types/agent.d.ts +8 -0
  87. package/dist/types/agent.d.ts.map +1 -1
  88. package/dist/types/agent.js.map +1 -1
  89. package/dist/types/config.d.ts +5 -0
  90. package/dist/types/config.d.ts.map +1 -1
  91. package/dist/types/config.js.map +1 -1
  92. package/dist/types/mission.d.ts +13 -3
  93. package/dist/types/mission.d.ts.map +1 -1
  94. package/package.json +6 -1
@@ -0,0 +1,8 @@
1
+ export * from "./types.js";
2
+ export * from "./store.js";
3
+ export * from "./state-machine.js";
4
+ export * from "./driver.js";
5
+ export * from "./dispatcher.js";
6
+ export * from "./occurrence.js";
7
+ export { SCHEDULE_LIMITS, normalizeCreateScheduleInput, normalizeCronExpression, normalizeScheduleInvocation, normalizeScheduleMetadata, normalizeScheduleTiming, normalizeUpdateScheduleInput, translateLegacyMissionSchedule, } from "./validation.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scheduling/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Schedule } from "./types.js";
2
+ export interface ScheduleOccurrence {
3
+ occurrenceAt: string;
4
+ localKey: string;
5
+ triggerId: string;
6
+ idempotencyKey: string;
7
+ }
8
+ export interface ListScheduleOccurrencesOptions {
9
+ after: Date | string;
10
+ through?: Date | string;
11
+ limit?: number;
12
+ }
13
+ export declare function nextScheduleOccurrence(schedule: Schedule, after: Date | string): ScheduleOccurrence | null;
14
+ export declare function previousScheduleOccurrence(schedule: Schedule, atOrBefore: Date | string): ScheduleOccurrence | null;
15
+ export declare function listScheduleOccurrences(schedule: Schedule, options: ListScheduleOccurrencesOptions): ScheduleOccurrence[];
16
+ export declare function scheduleOccurrenceIdentity(schedule: Schedule, occurrenceAt: Date | string): ScheduleOccurrence;
17
+ //# sourceMappingURL=occurrence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"occurrence.d.ts","sourceRoot":"","sources":["../../src/scheduling/occurrence.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,IAAI,GAAG,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,IAAI,GAAG,MAAM,GACnB,kBAAkB,GAAG,IAAI,CAiC3B;AAED,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,IAAI,GAAG,MAAM,GACxB,kBAAkB,GAAG,IAAI,CAgC3B;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,8BAA8B,GACtC,kBAAkB,EAAE,CAiCtB;AAED,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,IAAI,GAAG,MAAM,GAC1B,kBAAkB,CAmBpB"}
@@ -0,0 +1,164 @@
1
+ import { CronExpressionParser } from "cron-parser";
2
+ import { normalizeCronExpression } from "./validation.js";
3
+ const MAX_OCCURRENCE_LIST_SIZE = 1_000;
4
+ const SEARCH_HORIZON_YEARS = 5;
5
+ export function nextScheduleOccurrence(schedule, after) {
6
+ const afterDate = validDate(after, "Schedule occurrence after");
7
+ if (schedule.timing.kind === "once") {
8
+ const at = validDate(schedule.timing.at, "Schedule once occurrence");
9
+ return at.getTime() > afterDate.getTime()
10
+ ? scheduleOccurrenceIdentity(schedule, at)
11
+ : null;
12
+ }
13
+ const expression = normalizeCronExpression(schedule.timing.expression);
14
+ const endDate = addUtcYears(afterDate, SEARCH_HORIZON_YEARS);
15
+ const interval = CronExpressionParser.parse(expression, {
16
+ currentDate: afterDate,
17
+ endDate,
18
+ tz: schedule.timing.timezone,
19
+ });
20
+ const afterLocalKey = localMinuteKey(afterDate, schedule.timing.timezone);
21
+ for (;;) {
22
+ let candidate;
23
+ try {
24
+ candidate = interval.next();
25
+ }
26
+ catch (error) {
27
+ if (isRangeExhaustion(error))
28
+ return null;
29
+ throw error;
30
+ }
31
+ if (!matchesRequestedWallClock(interval, candidate))
32
+ continue;
33
+ const occurrence = identityUnchecked(schedule, candidate.toDate());
34
+ if (occurrence.localKey === afterLocalKey)
35
+ continue;
36
+ return occurrence;
37
+ }
38
+ }
39
+ export function previousScheduleOccurrence(schedule, atOrBefore) {
40
+ const bound = validDate(atOrBefore, "Schedule occurrence bound");
41
+ if (schedule.timing.kind === "once") {
42
+ const at = validDate(schedule.timing.at, "Schedule once occurrence");
43
+ return at.getTime() <= bound.getTime()
44
+ ? scheduleOccurrenceIdentity(schedule, at)
45
+ : null;
46
+ }
47
+ const expression = normalizeCronExpression(schedule.timing.expression);
48
+ const currentDate = new Date(bound.getTime() + 1);
49
+ const startDate = addUtcYears(bound, -SEARCH_HORIZON_YEARS);
50
+ const interval = CronExpressionParser.parse(expression, {
51
+ currentDate,
52
+ startDate,
53
+ tz: schedule.timing.timezone,
54
+ });
55
+ for (;;) {
56
+ let candidate;
57
+ try {
58
+ candidate = interval.prev();
59
+ }
60
+ catch (error) {
61
+ if (isRangeExhaustion(error))
62
+ return null;
63
+ throw error;
64
+ }
65
+ if (!matchesRequestedWallClock(interval, candidate))
66
+ continue;
67
+ const date = candidate.toDate();
68
+ if (date.getTime() <= bound.getTime()) {
69
+ return identityUnchecked(schedule, date);
70
+ }
71
+ }
72
+ }
73
+ export function listScheduleOccurrences(schedule, options) {
74
+ const after = validDate(options.after, "Schedule occurrence after");
75
+ const through = options.through === undefined
76
+ ? undefined
77
+ : validDate(options.through, "Schedule occurrence through");
78
+ if (through && through.getTime() <= after.getTime())
79
+ return [];
80
+ const limit = options.limit ?? 100;
81
+ if (!Number.isInteger(limit)
82
+ || limit < 1
83
+ || limit > MAX_OCCURRENCE_LIST_SIZE) {
84
+ throw new Error(`Schedule occurrence limit must be an integer between 1 and ${MAX_OCCURRENCE_LIST_SIZE}`);
85
+ }
86
+ const occurrences = [];
87
+ let cursor = after;
88
+ while (occurrences.length < limit) {
89
+ const occurrence = nextScheduleOccurrence(schedule, cursor);
90
+ if (!occurrence)
91
+ break;
92
+ if (through
93
+ && Date.parse(occurrence.occurrenceAt) > through.getTime()) {
94
+ break;
95
+ }
96
+ occurrences.push(occurrence);
97
+ cursor = new Date(occurrence.occurrenceAt);
98
+ }
99
+ return occurrences;
100
+ }
101
+ export function scheduleOccurrenceIdentity(schedule, occurrenceAt) {
102
+ const at = validDate(occurrenceAt, "Schedule occurrence");
103
+ if (schedule.timing.kind === "once") {
104
+ if (at.getTime() !== Date.parse(schedule.timing.at)) {
105
+ throw new Error(`Schedule occurrence ${at.toISOString()} does not match one-time schedule "${schedule.id}"`);
106
+ }
107
+ return identityUnchecked(schedule, at);
108
+ }
109
+ const previous = new Date(at.getTime() - 1);
110
+ const candidate = nextScheduleOccurrence(schedule, previous);
111
+ if (!candidate || candidate.occurrenceAt !== at.toISOString()) {
112
+ throw new Error(`Schedule occurrence ${at.toISOString()} does not match schedule "${schedule.id}"`);
113
+ }
114
+ return candidate;
115
+ }
116
+ function identityUnchecked(schedule, occurrenceAt) {
117
+ const occurrenceIso = occurrenceAt.toISOString();
118
+ const localKey = schedule.timing.kind === "cron"
119
+ ? localMinuteKey(occurrenceAt, schedule.timing.timezone)
120
+ : occurrenceIso;
121
+ return {
122
+ occurrenceAt: occurrenceIso,
123
+ localKey,
124
+ triggerId: `local:${schedule.id}:${localKey}`,
125
+ idempotencyKey: `schedule:${schedule.id}:${localKey}`,
126
+ };
127
+ }
128
+ function localMinuteKey(date, timezone) {
129
+ const formatter = new Intl.DateTimeFormat("en-CA", {
130
+ timeZone: timezone,
131
+ year: "numeric",
132
+ month: "2-digit",
133
+ day: "2-digit",
134
+ hour: "2-digit",
135
+ minute: "2-digit",
136
+ hourCycle: "h23",
137
+ });
138
+ const parts = Object.fromEntries(formatter.formatToParts(date)
139
+ .filter((part) => part.type !== "literal")
140
+ .map((part) => [part.type, part.value]));
141
+ return `${parts.year}-${parts.month}-${parts.day}T${parts.hour}:${parts.minute}[${timezone}]`;
142
+ }
143
+ function matchesRequestedWallClock(interval, candidate) {
144
+ const minutes = interval.fields.minute.values;
145
+ const hours = interval.fields.hour.values;
146
+ return minutes.includes(candidate.getMinutes())
147
+ && hours.includes(candidate.getHours());
148
+ }
149
+ function validDate(value, label) {
150
+ const date = new Date(value);
151
+ if (!Number.isFinite(date.getTime())) {
152
+ throw new Error(`${label} must be a valid date`);
153
+ }
154
+ return date;
155
+ }
156
+ function addUtcYears(date, years) {
157
+ const result = new Date(date);
158
+ result.setUTCFullYear(result.getUTCFullYear() + years);
159
+ return result;
160
+ }
161
+ function isRangeExhaustion(error) {
162
+ return error instanceof Error && /time span range/i.test(error.message);
163
+ }
164
+ //# sourceMappingURL=occurrence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"occurrence.js","sourceRoot":"","sources":["../../src/scheduling/occurrence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=occurrence.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"occurrence.test.d.ts","sourceRoot":"","sources":["../../src/scheduling/occurrence.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,148 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { listScheduleOccurrences, nextScheduleOccurrence, scheduleOccurrenceIdentity, } from "./occurrence.js";
3
+ function schedule(overrides = {}) {
4
+ return {
5
+ id: "schedule-1",
6
+ timing: {
7
+ kind: "cron",
8
+ expression: "0 9 * * *",
9
+ timezone: "UTC",
10
+ },
11
+ invocation: {
12
+ surface: "agent",
13
+ agentName: "assistant",
14
+ input: { prompt: "Run" },
15
+ },
16
+ status: "active",
17
+ policy: {
18
+ catchUp: "skip",
19
+ misfireGraceSeconds: 300,
20
+ maxConcurrency: 1,
21
+ },
22
+ metadata: {},
23
+ createdAt: "2026-01-01T00:00:00.000Z",
24
+ updatedAt: "2026-01-01T00:00:00.000Z",
25
+ revision: 1,
26
+ ...overrides,
27
+ };
28
+ }
29
+ describe("schedule occurrence calculation", () => {
30
+ it("returns the next UTC minute exclusively and normalizes seconds", () => {
31
+ const result = nextScheduleOccurrence(schedule({
32
+ timing: {
33
+ kind: "cron",
34
+ expression: "*/5 * * * *",
35
+ timezone: "UTC",
36
+ },
37
+ }), "2026-07-28T10:00:45.000Z");
38
+ expect(result).toEqual({
39
+ occurrenceAt: "2026-07-28T10:05:00.000Z",
40
+ localKey: "2026-07-28T10:05[UTC]",
41
+ triggerId: "local:schedule-1:2026-07-28T10:05[UTC]",
42
+ idempotencyKey: "schedule:schedule-1:2026-07-28T10:05[UTC]",
43
+ });
44
+ });
45
+ it("evaluates cron in its IANA timezone", () => {
46
+ const result = nextScheduleOccurrence(schedule({
47
+ timing: {
48
+ kind: "cron",
49
+ expression: "0 9 * * *",
50
+ timezone: "Europe/Rome",
51
+ },
52
+ }), "2026-07-28T06:00:00.000Z");
53
+ expect(result?.occurrenceAt).toBe("2026-07-28T07:00:00.000Z");
54
+ expect(result?.localKey).toBe("2026-07-28T09:00[Europe/Rome]");
55
+ });
56
+ it("uses standard cron OR semantics for day-of-month and day-of-week", () => {
57
+ const result = nextScheduleOccurrence(schedule({
58
+ timing: {
59
+ kind: "cron",
60
+ expression: "0 9 1 * 1",
61
+ timezone: "UTC",
62
+ },
63
+ }), "2026-09-01T09:00:00.000Z");
64
+ expect(result?.occurrenceAt).toBe("2026-09-07T09:00:00.000Z");
65
+ });
66
+ it("skips nonexistent local time during the spring DST transition", () => {
67
+ const result = nextScheduleOccurrence(schedule({
68
+ timing: {
69
+ kind: "cron",
70
+ expression: "30 2 * * *",
71
+ timezone: "Europe/Rome",
72
+ },
73
+ }), "2026-03-28T02:31:00.000Z");
74
+ expect(result).toMatchObject({
75
+ occurrenceAt: "2026-03-30T00:30:00.000Z",
76
+ localKey: "2026-03-30T02:30[Europe/Rome]",
77
+ });
78
+ });
79
+ it("deduplicates the repeated local minute during the fall DST transition", () => {
80
+ const results = listScheduleOccurrences(schedule({
81
+ timing: {
82
+ kind: "cron",
83
+ expression: "30 2 * * *",
84
+ timezone: "Europe/Rome",
85
+ },
86
+ }), {
87
+ after: "2026-10-24T23:00:00.000Z",
88
+ limit: 2,
89
+ });
90
+ expect(results.map((result) => result.localKey)).toEqual([
91
+ "2026-10-25T02:30[Europe/Rome]",
92
+ "2026-10-26T02:30[Europe/Rome]",
93
+ ]);
94
+ expect(new Set(results.map((result) => result.idempotencyKey)).size).toBe(2);
95
+ });
96
+ it("returns a one-time occurrence once and only once", () => {
97
+ const once = schedule({
98
+ timing: {
99
+ kind: "once",
100
+ at: "2026-07-28T10:30:00.000Z",
101
+ timezone: "Europe/Rome",
102
+ },
103
+ });
104
+ expect(nextScheduleOccurrence(once, "2026-07-28T10:29:59.999Z")).toMatchObject({
105
+ occurrenceAt: "2026-07-28T10:30:00.000Z",
106
+ localKey: "2026-07-28T10:30:00.000Z",
107
+ });
108
+ expect(nextScheduleOccurrence(once, "2026-07-28T10:30:00.000Z")).toBeNull();
109
+ });
110
+ it("respects inclusive through bounds and hard list limits", () => {
111
+ const everyMinute = schedule({
112
+ timing: {
113
+ kind: "cron",
114
+ expression: "* * * * *",
115
+ timezone: "UTC",
116
+ },
117
+ });
118
+ expect(listScheduleOccurrences(everyMinute, {
119
+ after: "2026-07-28T10:00:00.000Z",
120
+ through: "2026-07-28T10:02:00.000Z",
121
+ limit: 10,
122
+ }).map((item) => item.occurrenceAt)).toEqual([
123
+ "2026-07-28T10:01:00.000Z",
124
+ "2026-07-28T10:02:00.000Z",
125
+ ]);
126
+ expect(listScheduleOccurrences(everyMinute, {
127
+ after: "2026-07-28T10:00:00.000Z",
128
+ limit: 1,
129
+ })).toHaveLength(1);
130
+ expect(() => listScheduleOccurrences(everyMinute, {
131
+ after: "2026-07-28T10:00:00.000Z",
132
+ limit: 0,
133
+ })).toThrow(/limit/i);
134
+ });
135
+ it("fails closed for invalid dates and mismatched occurrence identities", () => {
136
+ const valid = schedule();
137
+ expect(() => nextScheduleOccurrence(valid, "not-a-date")).toThrow(/after/i);
138
+ expect(() => scheduleOccurrenceIdentity(valid, "2026-07-28T10:00:00.000Z")).toThrow(/does not match/i);
139
+ });
140
+ it("scopes occurrence identities by schedule", () => {
141
+ const at = "2026-07-28T09:00:00.000Z";
142
+ const first = scheduleOccurrenceIdentity(schedule(), at);
143
+ const second = scheduleOccurrenceIdentity(schedule({ id: "schedule-2" }), at);
144
+ expect(first.localKey).toBe(second.localKey);
145
+ expect(first.idempotencyKey).not.toBe(second.idempotencyKey);
146
+ });
147
+ });
148
+ //# sourceMappingURL=occurrence.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"occurrence.test.js","sourceRoot":"","sources":["../../src/scheduling/occurrence.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ScheduleRunStatus, ScheduleStatus } from "./types.js";
2
+ export declare const SCHEDULE_STATUS_TRANSITIONS: Readonly<Record<ScheduleStatus, readonly ScheduleStatus[]>>;
3
+ export declare const SCHEDULE_RUN_STATUS_TRANSITIONS: Readonly<Record<ScheduleRunStatus, readonly ScheduleRunStatus[]>>;
4
+ export declare function isScheduleStatusTransitionAllowed(from: ScheduleStatus, to: ScheduleStatus): boolean;
5
+ export declare function assertScheduleStatusTransition(from: ScheduleStatus, to: ScheduleStatus): void;
6
+ export declare function isScheduleRunStatusTransitionAllowed(from: ScheduleRunStatus, to: ScheduleRunStatus): boolean;
7
+ export declare function assertScheduleRunStatusTransition(from: ScheduleRunStatus, to: ScheduleRunStatus): void;
8
+ export declare const TERMINAL_SCHEDULE_RUN_STATUSES: ReadonlySet<ScheduleRunStatus>;
9
+ export declare function isTerminalScheduleRunStatus(status: ScheduleRunStatus): boolean;
10
+ //# sourceMappingURL=state-machine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../../src/scheduling/state-machine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEpE,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAChD,MAAM,CAAC,cAAc,EAAE,SAAS,cAAc,EAAE,CAAC,CAMjD,CAAC;AAEH,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CACpD,MAAM,CAAC,iBAAiB,EAAE,SAAS,iBAAiB,EAAE,CAAC,CASvD,CAAC;AAEH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,cAAc,EACpB,EAAE,EAAE,cAAc,GACjB,OAAO,CAET;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,cAAc,EACpB,EAAE,EAAE,cAAc,GACjB,IAAI,CAIN;AAED,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,iBAAiB,EACvB,EAAE,EAAE,iBAAiB,GACpB,OAAO,CAET;AAED,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,iBAAiB,EACvB,EAAE,EAAE,iBAAiB,GACpB,IAAI,CAIN;AAED,eAAO,MAAM,8BAA8B,EAAE,WAAW,CAAC,iBAAiB,CAChB,CAAC;AAE3D,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAE9E"}
@@ -0,0 +1,36 @@
1
+ export const SCHEDULE_STATUS_TRANSITIONS = Object.freeze({
2
+ active: ["paused", "completed", "deleted"],
3
+ paused: ["active", "completed", "deleted"],
4
+ completed: ["deleted"],
5
+ deleted: [],
6
+ });
7
+ export const SCHEDULE_RUN_STATUS_TRANSITIONS = Object.freeze({
8
+ pending: ["claimed", "skipped", "cancelled"],
9
+ claimed: ["pending", "running", "failed", "skipped", "cancelled"],
10
+ running: ["claimed", "pending", "succeeded", "failed", "cancelled"],
11
+ succeeded: [],
12
+ failed: [],
13
+ skipped: [],
14
+ cancelled: [],
15
+ });
16
+ export function isScheduleStatusTransitionAllowed(from, to) {
17
+ return from === to || SCHEDULE_STATUS_TRANSITIONS[from].includes(to);
18
+ }
19
+ export function assertScheduleStatusTransition(from, to) {
20
+ if (!isScheduleStatusTransitionAllowed(from, to)) {
21
+ throw new Error(`Invalid schedule status transition: ${from} -> ${to}`);
22
+ }
23
+ }
24
+ export function isScheduleRunStatusTransitionAllowed(from, to) {
25
+ return from === to || SCHEDULE_RUN_STATUS_TRANSITIONS[from].includes(to);
26
+ }
27
+ export function assertScheduleRunStatusTransition(from, to) {
28
+ if (!isScheduleRunStatusTransitionAllowed(from, to)) {
29
+ throw new Error(`Invalid schedule run status transition: ${from} -> ${to}`);
30
+ }
31
+ }
32
+ export const TERMINAL_SCHEDULE_RUN_STATUSES = new Set(["succeeded", "failed", "skipped", "cancelled"]);
33
+ export function isTerminalScheduleRunStatus(status) {
34
+ return TERMINAL_SCHEDULE_RUN_STATUSES.has(status);
35
+ }
36
+ //# sourceMappingURL=state-machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.js","sourceRoot":"","sources":["../../src/scheduling/state-machine.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,2BAA2B,GAEpC,MAAM,CAAC,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAU;IACnD,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAU;IACnD,SAAS,EAAE,CAAC,SAAS,CAAU;IAC/B,OAAO,EAAE,EAAW;CACrB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,+BAA+B,GAExC,MAAM,CAAC,MAAM,CAAC;IAChB,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAU;IACrD,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAU;IAC1E,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAU;IAC5E,SAAS,EAAE,EAAW;IACtB,MAAM,EAAE,EAAW;IACnB,OAAO,EAAE,EAAW;IACpB,SAAS,EAAE,EAAW;CACvB,CAAC,CAAC;AAEH,MAAM,UAAU,iCAAiC,CAC/C,IAAoB,EACpB,EAAkB;IAElB,OAAO,IAAI,KAAK,EAAE,IAAI,2BAA2B,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,IAAoB,EACpB,EAAkB;IAElB,IAAI,CAAC,iCAAiC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,IAAuB,EACvB,EAAqB;IAErB,OAAO,IAAI,KAAK,EAAE,IAAI,+BAA+B,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC/C,IAAuB,EACvB,EAAqB;IAErB,IAAI,CAAC,oCAAoC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,2CAA2C,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,8BAA8B,GACzC,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;AAE3D,MAAM,UAAU,2BAA2B,CAAC,MAAyB;IACnE,OAAO,8BAA8B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=state-machine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.test.d.ts","sourceRoot":"","sources":["../../src/scheduling/state-machine.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { SCHEDULE_RUN_STATUS_TRANSITIONS, SCHEDULE_STATUS_TRANSITIONS, assertScheduleRunStatusTransition, assertScheduleStatusTransition, isScheduleRunStatusTransitionAllowed, isScheduleStatusTransitionAllowed, isTerminalScheduleRunStatus, } from "./index.js";
3
+ describe("schedule lifecycle state machine", () => {
4
+ it.each([
5
+ ["active", "paused"],
6
+ ["active", "completed"],
7
+ ["active", "deleted"],
8
+ ["paused", "active"],
9
+ ["paused", "completed"],
10
+ ["paused", "deleted"],
11
+ ["completed", "deleted"],
12
+ ])("allows %s -> %s", (from, to) => {
13
+ expect(isScheduleStatusTransitionAllowed(from, to)).toBe(true);
14
+ expect(() => assertScheduleStatusTransition(from, to)).not.toThrow();
15
+ });
16
+ it.each([
17
+ ["completed", "active"],
18
+ ["completed", "paused"],
19
+ ["deleted", "active"],
20
+ ["deleted", "paused"],
21
+ ["deleted", "completed"],
22
+ ])("rejects %s -> %s", (from, to) => {
23
+ expect(isScheduleStatusTransitionAllowed(from, to)).toBe(false);
24
+ expect(() => assertScheduleStatusTransition(from, to)).toThrow(`${from} -> ${to}`);
25
+ });
26
+ it("allows idempotent same-state checks without adding transition edges", () => {
27
+ const states = ["active", "paused", "completed", "deleted"];
28
+ for (const state of states) {
29
+ expect(isScheduleStatusTransitionAllowed(state, state)).toBe(true);
30
+ expect(SCHEDULE_STATUS_TRANSITIONS[state]).not.toContain(state);
31
+ }
32
+ });
33
+ });
34
+ describe("schedule run lifecycle state machine", () => {
35
+ it.each([
36
+ ["pending", "claimed"],
37
+ ["pending", "skipped"],
38
+ ["pending", "cancelled"],
39
+ ["claimed", "pending"],
40
+ ["claimed", "running"],
41
+ ["claimed", "failed"],
42
+ ["running", "pending"],
43
+ ["running", "claimed"],
44
+ ["running", "succeeded"],
45
+ ["running", "failed"],
46
+ ["running", "cancelled"],
47
+ ])("allows %s -> %s", (from, to) => {
48
+ expect(isScheduleRunStatusTransitionAllowed(from, to)).toBe(true);
49
+ expect(() => assertScheduleRunStatusTransition(from, to)).not.toThrow();
50
+ });
51
+ it.each([
52
+ ["pending", "succeeded"],
53
+ ["succeeded", "running"],
54
+ ["failed", "claimed"],
55
+ ["skipped", "pending"],
56
+ ["cancelled", "claimed"],
57
+ ])("rejects %s -> %s", (from, to) => {
58
+ expect(isScheduleRunStatusTransitionAllowed(from, to)).toBe(false);
59
+ expect(() => assertScheduleRunStatusTransition(from, to)).toThrow(`${from} -> ${to}`);
60
+ });
61
+ it("keeps every terminal state terminal", () => {
62
+ const terminal = [
63
+ "succeeded",
64
+ "failed",
65
+ "skipped",
66
+ "cancelled",
67
+ ];
68
+ for (const state of terminal) {
69
+ expect(isTerminalScheduleRunStatus(state)).toBe(true);
70
+ expect(SCHEDULE_RUN_STATUS_TRANSITIONS[state]).toEqual([]);
71
+ }
72
+ expect(isTerminalScheduleRunStatus("pending")).toBe(false);
73
+ expect(isTerminalScheduleRunStatus("claimed")).toBe(false);
74
+ expect(isTerminalScheduleRunStatus("running")).toBe(false);
75
+ });
76
+ });
77
+ //# sourceMappingURL=state-machine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.test.js","sourceRoot":"","sources":["../../src/scheduling/state-machine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ import type { CreateScheduleInput, Schedule, ScheduleDriverRegistration, ScheduleLease, ScheduleMetadata, ScheduleRun, ScheduleRunError, ScheduleRunReferences, ScheduleRunStatus, ScheduleStatus, UpdateScheduleInput } from "./types.js";
2
+ export interface ScheduleFilter {
3
+ status?: ScheduleStatus | ScheduleStatus[];
4
+ surface?: Schedule["invocation"]["surface"];
5
+ includeDeleted?: boolean;
6
+ }
7
+ export interface ScheduleRunFilter {
8
+ scheduleId?: string;
9
+ status?: ScheduleRunStatus | ScheduleRunStatus[];
10
+ limit?: number;
11
+ order?: "asc" | "desc";
12
+ }
13
+ export interface ScheduleMutationOptions {
14
+ expectedRevision?: number;
15
+ }
16
+ export interface CreateScheduleRunInput {
17
+ id?: string;
18
+ scheduleId: string;
19
+ occurrenceAt: string;
20
+ triggerId: string;
21
+ idempotencyKey: string;
22
+ }
23
+ export interface CompleteScheduleRunInput {
24
+ lease: ScheduleLease;
25
+ status: Extract<ScheduleRunStatus, "succeeded" | "failed" | "skipped" | "cancelled">;
26
+ references: ScheduleRunReferences;
27
+ result?: ScheduleMetadata;
28
+ error?: ScheduleRunError;
29
+ }
30
+ export interface ScheduleOperationalStatePatch {
31
+ nextOccurrenceAt?: string | null;
32
+ lastOccurrenceAt?: string | null;
33
+ driver?: ScheduleDriverRegistration | null;
34
+ }
35
+ export interface ScheduleStore {
36
+ create(input: CreateScheduleInput): Promise<Schedule>;
37
+ list(filter?: ScheduleFilter): Promise<Schedule[]>;
38
+ get(id: string): Promise<Schedule | null>;
39
+ update(id: string, patch: UpdateScheduleInput, options?: ScheduleMutationOptions): Promise<Schedule>;
40
+ markDeleted(id: string, options?: ScheduleMutationOptions): Promise<void>;
41
+ updateOperationalState(id: string, patch: ScheduleOperationalStatePatch, options?: ScheduleMutationOptions): Promise<Schedule>;
42
+ createRun(input: CreateScheduleRunInput): Promise<ScheduleRun>;
43
+ getRun(id: string): Promise<ScheduleRun | null>;
44
+ listRuns(filter?: ScheduleRunFilter): Promise<ScheduleRun[]>;
45
+ claimRun(id: string, lease: ScheduleLease): Promise<ScheduleRun | null>;
46
+ renewLease(id: string, lease: ScheduleLease): Promise<boolean>;
47
+ startRun(id: string, lease: ScheduleLease): Promise<ScheduleRun>;
48
+ releaseRun(id: string, lease: ScheduleLease): Promise<ScheduleRun>;
49
+ completeRun(id: string, input: CompleteScheduleRunInput): Promise<ScheduleRun>;
50
+ countActiveRuns(scheduleId: string): Promise<number>;
51
+ }
52
+ export interface InMemoryScheduleStoreOptions {
53
+ now?: () => Date | string;
54
+ createId?: (kind: "schedule" | "schedule-run") => string;
55
+ }
56
+ export declare class ScheduleStoreError extends Error {
57
+ readonly code: "NOT_FOUND" | "CONFLICT" | "INVALID_STATE";
58
+ constructor(message: string, code: "NOT_FOUND" | "CONFLICT" | "INVALID_STATE");
59
+ }
60
+ export declare class ScheduleNotFoundError extends ScheduleStoreError {
61
+ constructor(entity: "Schedule" | "Schedule run", id: string);
62
+ }
63
+ export declare class ScheduleConflictError extends ScheduleStoreError {
64
+ constructor(message: string);
65
+ }
66
+ export declare class ScheduleInvalidStateError extends ScheduleStoreError {
67
+ constructor(message: string);
68
+ }
69
+ export declare class InMemoryScheduleStore implements ScheduleStore {
70
+ private readonly schedules;
71
+ private readonly runs;
72
+ private readonly runIdsByIdempotencyKey;
73
+ private readonly options;
74
+ constructor(options?: InMemoryScheduleStoreOptions);
75
+ create(input: CreateScheduleInput): Promise<Schedule>;
76
+ list(filter?: ScheduleFilter): Promise<Schedule[]>;
77
+ get(id: string): Promise<Schedule | null>;
78
+ update(id: string, patch: UpdateScheduleInput, options?: ScheduleMutationOptions): Promise<Schedule>;
79
+ markDeleted(id: string, options?: ScheduleMutationOptions): Promise<void>;
80
+ updateOperationalState(id: string, patch: ScheduleOperationalStatePatch, options?: ScheduleMutationOptions): Promise<Schedule>;
81
+ createRun(input: CreateScheduleRunInput): Promise<ScheduleRun>;
82
+ getRun(id: string): Promise<ScheduleRun | null>;
83
+ listRuns(filter?: ScheduleRunFilter): Promise<ScheduleRun[]>;
84
+ claimRun(id: string, lease: ScheduleLease): Promise<ScheduleRun | null>;
85
+ renewLease(id: string, lease: ScheduleLease): Promise<boolean>;
86
+ startRun(id: string, lease: ScheduleLease): Promise<ScheduleRun>;
87
+ releaseRun(id: string, lease: ScheduleLease): Promise<ScheduleRun>;
88
+ completeRun(id: string, input: CompleteScheduleRunInput): Promise<ScheduleRun>;
89
+ countActiveRuns(scheduleId: string): Promise<number>;
90
+ private requireSchedule;
91
+ private requireRun;
92
+ private requireOwnedActiveRun;
93
+ private now;
94
+ }
95
+ export declare function normalizeCreateScheduleRunInput(input: CreateScheduleRunInput): CreateScheduleRunInput;
96
+ export declare function normalizeScheduleLease(value: ScheduleLease, now: Date, requireFuture?: boolean): ScheduleLease;
97
+ export declare function normalizeCompleteScheduleRunInput(value: CompleteScheduleRunInput, now: Date): CompleteScheduleRunInput;
98
+ export declare function normalizeScheduleOperationalStatePatch(value: ScheduleOperationalStatePatch): ScheduleOperationalStatePatch;
99
+ export declare function assertSameScheduleOccurrence(existing: ScheduleRun, input: CreateScheduleRunInput): void;
100
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/scheduling/store.ts"],"names":[],"mappings":"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"}