clanka 0.2.18 → 0.2.20
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/Agent.d.ts.map +1 -1
- package/dist/Agent.js +2 -1
- package/dist/Agent.js.map +1 -1
- package/dist/CodeChunker.d.ts +4 -0
- package/dist/CodeChunker.d.ts.map +1 -1
- package/dist/CodeChunker.js +64 -14
- package/dist/CodeChunker.js.map +1 -1
- package/dist/CodeChunker.test.js +71 -0
- package/dist/CodeChunker.test.js.map +1 -1
- package/dist/ScriptPreprocessing.d.ts.map +1 -1
- package/dist/ScriptPreprocessing.js +128 -9
- package/dist/ScriptPreprocessing.js.map +1 -1
- package/dist/ScriptPreprocessing.test.js +4 -0
- package/dist/ScriptPreprocessing.test.js.map +1 -1
- package/dist/SemanticSearch.d.ts +1 -0
- package/dist/SemanticSearch.d.ts.map +1 -1
- package/dist/SemanticSearch.js +4 -2
- package/dist/SemanticSearch.js.map +1 -1
- package/package.json +10 -10
- package/src/Agent.ts +2 -1
- package/src/CodeChunker.test.ts +77 -0
- package/src/CodeChunker.ts +105 -19
- package/src/ScriptPreprocessing.test.ts +4 -0
- package/src/ScriptPreprocessing.ts +161 -9
- package/src/SemanticSearch.ts +7 -2
- package/src/fixtures/patch10-broken.txt +95 -0
- package/src/fixtures/patch10-fixed.txt +95 -0
- package/src/fixtures/patch11-broken.txt +219 -0
- package/src/fixtures/patch11-fixed.txt +219 -0
- package/src/fixtures/patch8-broken.txt +30 -0
- package/src/fixtures/patch8-fixed.txt +30 -0
- package/src/fixtures/patch9-broken.txt +10 -0
- package/src/fixtures/patch9-fixed.txt +10 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
const patch = `*** Begin Patch
|
|
2
|
+
*** Update File: packages/effect/src/Cron.ts
|
|
3
|
+
@@
|
|
4
|
+
export const next = (cron: Cron, now?: DateTime.DateTime.Input): Date => {
|
|
5
|
+
+ return stepCron(cron, now, "next")
|
|
6
|
+
+}
|
|
7
|
+
+
|
|
8
|
+
+/**
|
|
9
|
+
+ * Returns the previous scheduled date/time for the given Cron instance.
|
|
10
|
+
+ *
|
|
11
|
+
+ * This function calculates the most recent date and time when the cron
|
|
12
|
+
+ * schedule should have triggered, before the specified date (or current
|
|
13
|
+
+ * time if not provided).
|
|
14
|
+
+ *
|
|
15
|
+
+ * @example
|
|
16
|
+
+ * ```ts
|
|
17
|
+
+ * import { Cron, Result } from "effect"
|
|
18
|
+
+ *
|
|
19
|
+
+ * const cron = Result.getOrThrow(Cron.parse("0 0 4 8-14 * *"))
|
|
20
|
+
+ *
|
|
21
|
+
+ * // Get previous run before a specific date
|
|
22
|
+
+ * const before = new Date("2021-01-15T00:00:00Z")
|
|
23
|
+
+ * const previousRun = Cron.prev(cron, before)
|
|
24
|
+
+ * console.log(previousRun) // 2021-01-14T04:00:00.000Z
|
|
25
|
+
+ *
|
|
26
|
+
+ * // Get previous run from current time
|
|
27
|
+
+ * const previousFromNow = Cron.prev(cron)
|
|
28
|
+
+ * console.log(previousFromNow) // Previous occurrence from now
|
|
29
|
+
+ * ```
|
|
30
|
+
+ *
|
|
31
|
+
+ * @since 4.0.0
|
|
32
|
+
+ * @category utils
|
|
33
|
+
+ */
|
|
34
|
+
+export const prev = (cron: Cron, now?: DateTime.DateTime.Input): Date => {
|
|
35
|
+
+ return stepCron(cron, now, "prev")
|
|
36
|
+
+}
|
|
37
|
+
+
|
|
38
|
+
+const stepCron = (cron: Cron, now: DateTime.DateTime.Input | undefined, direction: "next" | "prev"): Date => {
|
|
39
|
+
const tz = Option.getOrUndefined(cron.tz)
|
|
40
|
+
const zoned = dateTime.makeZonedUnsafe(now ?? new Date(), {
|
|
41
|
+
timeZone: tz
|
|
42
|
+
})
|
|
43
|
+
+
|
|
44
|
+
+ const reverse = direction === "prev"
|
|
45
|
+
+ const tick = reverse ? -1 : 1
|
|
46
|
+
+ const table = cron[direction]
|
|
47
|
+
+ const boundary = reverse ? cron.last : cron.first
|
|
48
|
+
+
|
|
49
|
+
+ const needsStep = reverse ?
|
|
50
|
+
+ (next: number, current: number) => next < current :
|
|
51
|
+
+ (next: number, current: number) => next > current
|
|
52
|
+
|
|
53
|
+
const utc = tz !== undefined && dateTime.isTimeZoneNamed(tz) && tz.id === "UTC"
|
|
54
|
+
const adjustDst = utc ? constVoid : (current: Date) => {
|
|
55
|
+
const adjusted = dateTime.makeZonedUnsafe(current, {
|
|
56
|
+
timeZone: zoned.zone,
|
|
57
|
+
- adjustForTimeZone: true
|
|
58
|
+
+ adjustForTimeZone: true,
|
|
59
|
+
+ disambiguation: reverse ? "later" : undefined
|
|
60
|
+
}).pipe(dateTime.toDate)
|
|
61
|
+
|
|
62
|
+
- // TODO: This implementation currently only skips forward when transitioning into daylight savings time.
|
|
63
|
+
const drift = current.getTime() - adjusted.getTime()
|
|
64
|
+
- if (drift > 0) {
|
|
65
|
+
- current.setTime(current.getTime() + drift)
|
|
66
|
+
+ if (reverse ? drift !== 0 : drift > 0) {
|
|
67
|
+
+ current.setTime(adjusted.getTime())
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const result = dateTime.mutate(zoned, (current) => {
|
|
72
|
+
- current.setUTCSeconds(current.getUTCSeconds() + 1, 0)
|
|
73
|
+
+ current.setUTCSeconds(current.getUTCSeconds() + tick, 0)
|
|
74
|
+
|
|
75
|
+
for (let i = 0; i < 10_000; i++) {
|
|
76
|
+
if (cron.seconds.size !== 0) {
|
|
77
|
+
const currentSecond = current.getUTCSeconds()
|
|
78
|
+
- const nextSecond = cron.next.second[currentSecond]
|
|
79
|
+
+ const nextSecond = table.second[currentSecond]
|
|
80
|
+
if (nextSecond === undefined) {
|
|
81
|
+
- current.setUTCMinutes(current.getUTCMinutes() + 1, cron.first.second)
|
|
82
|
+
+ current.setUTCMinutes(current.getUTCMinutes() + tick, boundary.second)
|
|
83
|
+
adjustDst(current)
|
|
84
|
+
continue
|
|
85
|
+
}
|
|
86
|
+
- if (nextSecond > currentSecond) {
|
|
87
|
+
+ if (needsStep(nextSecond, currentSecond)) {
|
|
88
|
+
current.setUTCSeconds(nextSecond)
|
|
89
|
+
adjustDst(current)
|
|
90
|
+
continue
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (cron.minutes.size !== 0) {
|
|
95
|
+
const currentMinute = current.getUTCMinutes()
|
|
96
|
+
- const nextMinute = cron.next.minute[currentMinute]
|
|
97
|
+
+ const nextMinute = table.minute[currentMinute]
|
|
98
|
+
if (nextMinute === undefined) {
|
|
99
|
+
- current.setUTCHours(current.getUTCHours() + 1, cron.first.minute, cron.first.second)
|
|
100
|
+
+ current.setUTCHours(current.getUTCHours() + tick, boundary.minute, boundary.second)
|
|
101
|
+
adjustDst(current)
|
|
102
|
+
continue
|
|
103
|
+
}
|
|
104
|
+
- if (nextMinute > currentMinute) {
|
|
105
|
+
- current.setUTCMinutes(nextMinute, cron.first.second)
|
|
106
|
+
+ if (needsStep(nextMinute, currentMinute)) {
|
|
107
|
+
+ current.setUTCMinutes(nextMinute, boundary.second)
|
|
108
|
+
adjustDst(current)
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (cron.hours.size !== 0) {
|
|
114
|
+
const currentHour = current.getUTCHours()
|
|
115
|
+
- const nextHour = cron.next.hour[currentHour]
|
|
116
|
+
+ const nextHour = table.hour[currentHour]
|
|
117
|
+
if (nextHour === undefined) {
|
|
118
|
+
- current.setUTCDate(current.getUTCDate() + 1)
|
|
119
|
+
- current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
|
|
120
|
+
+ current.setUTCDate(current.getUTCDate() + tick)
|
|
121
|
+
+ current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
|
|
122
|
+
adjustDst(current)
|
|
123
|
+
continue
|
|
124
|
+
}
|
|
125
|
+
- if (nextHour > currentHour) {
|
|
126
|
+
- current.setUTCHours(nextHour, cron.first.minute, cron.first.second)
|
|
127
|
+
+ if (needsStep(nextHour, currentHour)) {
|
|
128
|
+
+ current.setUTCHours(nextHour, boundary.minute, boundary.second)
|
|
129
|
+
adjustDst(current)
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (cron.weekdays.size !== 0 || cron.days.size !== 0) {
|
|
135
|
+
- let a: number = Infinity
|
|
136
|
+
- let b: number = Infinity
|
|
137
|
+
+ let a: number = reverse ? -Infinity : Infinity
|
|
138
|
+
+ let b: number = reverse ? -Infinity : Infinity
|
|
139
|
+
|
|
140
|
+
if (cron.weekdays.size !== 0) {
|
|
141
|
+
const currentWeekday = current.getUTCDay()
|
|
142
|
+
- const nextWeekday = cron.next.weekday[currentWeekday]
|
|
143
|
+
- a = nextWeekday === undefined ? 7 - currentWeekday + cron.first.weekday : nextWeekday - currentWeekday
|
|
144
|
+
+ const nextWeekday = table.weekday[currentWeekday]
|
|
145
|
+
+ if (nextWeekday === undefined) {
|
|
146
|
+
+ a = reverse ?
|
|
147
|
+
+ currentWeekday - 7 + boundary.weekday :
|
|
148
|
+
+ 7 - currentWeekday + boundary.weekday
|
|
149
|
+
+ } else {
|
|
150
|
+
+ a = nextWeekday - currentWeekday
|
|
151
|
+
+ }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (cron.days.size !== 0 && a !== 0) {
|
|
155
|
+
const currentDay = current.getUTCDate()
|
|
156
|
+
- const nextDay = cron.next.day[currentDay]
|
|
157
|
+
- b = nextDay === undefined ? daysInMonth(current) - currentDay + cron.first.day : nextDay - currentDay
|
|
158
|
+
+ const nextDay = table.day[currentDay]
|
|
159
|
+
+ if (nextDay === undefined) {
|
|
160
|
+
+ if (reverse) {
|
|
161
|
+
+ const prevMonthDays = daysInMonth(new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), 0)))
|
|
162
|
+
+ b = -(currentDay + (prevMonthDays - boundary.day))
|
|
163
|
+
+ } else {
|
|
164
|
+
+ b = daysInMonth(current) - currentDay + boundary.day
|
|
165
|
+
+ }
|
|
166
|
+
+ } else {
|
|
167
|
+
+ b = nextDay - currentDay
|
|
168
|
+
+ }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
- const addDays = Math.min(a, b)
|
|
172
|
+
+ const addDays = reverse ? Math.max(a, b) : Math.min(a, b)
|
|
173
|
+
if (addDays !== 0) {
|
|
174
|
+
current.setUTCDate(current.getUTCDate() + addDays)
|
|
175
|
+
- current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
|
|
176
|
+
+ current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
|
|
177
|
+
adjustDst(current)
|
|
178
|
+
continue
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (cron.months.size !== 0) {
|
|
183
|
+
const currentMonth = current.getUTCMonth() + 1
|
|
184
|
+
- const nextMonth = cron.next.month[currentMonth]
|
|
185
|
+
+ const nextMonth = table.month[currentMonth]
|
|
186
|
+
+ const clampBoundaryDay = (targetMonthIndex: number): number => {
|
|
187
|
+
+ if (cron.days.size !== 0) {
|
|
188
|
+
+ return boundary.day
|
|
189
|
+
+ }
|
|
190
|
+
+ const maxDayInMonth = daysInMonth(new Date(Date.UTC(current.getUTCFullYear(), targetMonthIndex + 1, 0)))
|
|
191
|
+
+ return Math.min(boundary.day, maxDayInMonth)
|
|
192
|
+
+ }
|
|
193
|
+
if (nextMonth === undefined) {
|
|
194
|
+
- current.setUTCFullYear(current.getUTCFullYear() + 1)
|
|
195
|
+
- current.setUTCMonth(cron.first.month, cron.first.day)
|
|
196
|
+
- current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
|
|
197
|
+
+ current.setUTCFullYear(current.getUTCFullYear() + tick)
|
|
198
|
+
+ current.setUTCMonth(boundary.month, clampBoundaryDay(boundary.month))
|
|
199
|
+
+ current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
|
|
200
|
+
adjustDst(current)
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
- if (nextMonth > currentMonth) {
|
|
204
|
+
- current.setUTCMonth(nextMonth - 1, cron.first.day)
|
|
205
|
+
- current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
|
|
206
|
+
+ if (needsStep(nextMonth, currentMonth)) {
|
|
207
|
+
+ const targetMonthIndex = nextMonth - 1
|
|
208
|
+
+ current.setUTCMonth(targetMonthIndex, clampBoundaryDay(targetMonthIndex))
|
|
209
|
+
+ current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
|
|
210
|
+
adjustDst(current)
|
|
211
|
+
continue
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
@@
|
|
215
|
+
- throw new Error("Unable to find next cron date")
|
|
216
|
+
+ throw new Error(`Unable to find ${direction} cron date`)
|
|
217
|
+
})
|
|
218
|
+
*** End Patch`
|
|
219
|
+
console.log(await applyPatch(patch))
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
const patch = `*** Begin Patch
|
|
2
|
+
*** Update File: packages/effect/src/Cron.ts
|
|
3
|
+
@@
|
|
4
|
+
export const next = (cron: Cron, now?: DateTime.DateTime.Input): Date => {
|
|
5
|
+
+ return stepCron(cron, now, "next")
|
|
6
|
+
+}
|
|
7
|
+
+
|
|
8
|
+
+/**
|
|
9
|
+
+ * Returns the previous scheduled date/time for the given Cron instance.
|
|
10
|
+
+ *
|
|
11
|
+
+ * This function calculates the most recent date and time when the cron
|
|
12
|
+
+ * schedule should have triggered, before the specified date (or current
|
|
13
|
+
+ * time if not provided).
|
|
14
|
+
+ *
|
|
15
|
+
+ * @example
|
|
16
|
+
+ * \`\`\`ts
|
|
17
|
+
+ * import { Cron, Result } from "effect"
|
|
18
|
+
+ *
|
|
19
|
+
+ * const cron = Result.getOrThrow(Cron.parse("0 0 4 8-14 * *"))
|
|
20
|
+
+ *
|
|
21
|
+
+ * // Get previous run before a specific date
|
|
22
|
+
+ * const before = new Date("2021-01-15T00:00:00Z")
|
|
23
|
+
+ * const previousRun = Cron.prev(cron, before)
|
|
24
|
+
+ * console.log(previousRun) // 2021-01-14T04:00:00.000Z
|
|
25
|
+
+ *
|
|
26
|
+
+ * // Get previous run from current time
|
|
27
|
+
+ * const previousFromNow = Cron.prev(cron)
|
|
28
|
+
+ * console.log(previousFromNow) // Previous occurrence from now
|
|
29
|
+
+ * \`\`\`
|
|
30
|
+
+ *
|
|
31
|
+
+ * @since 4.0.0
|
|
32
|
+
+ * @category utils
|
|
33
|
+
+ */
|
|
34
|
+
+export const prev = (cron: Cron, now?: DateTime.DateTime.Input): Date => {
|
|
35
|
+
+ return stepCron(cron, now, "prev")
|
|
36
|
+
+}
|
|
37
|
+
+
|
|
38
|
+
+const stepCron = (cron: Cron, now: DateTime.DateTime.Input | undefined, direction: "next" | "prev"): Date => {
|
|
39
|
+
const tz = Option.getOrUndefined(cron.tz)
|
|
40
|
+
const zoned = dateTime.makeZonedUnsafe(now ?? new Date(), {
|
|
41
|
+
timeZone: tz
|
|
42
|
+
})
|
|
43
|
+
+
|
|
44
|
+
+ const reverse = direction === "prev"
|
|
45
|
+
+ const tick = reverse ? -1 : 1
|
|
46
|
+
+ const table = cron[direction]
|
|
47
|
+
+ const boundary = reverse ? cron.last : cron.first
|
|
48
|
+
+
|
|
49
|
+
+ const needsStep = reverse ?
|
|
50
|
+
+ (next: number, current: number) => next < current :
|
|
51
|
+
+ (next: number, current: number) => next > current
|
|
52
|
+
|
|
53
|
+
const utc = tz !== undefined && dateTime.isTimeZoneNamed(tz) && tz.id === "UTC"
|
|
54
|
+
const adjustDst = utc ? constVoid : (current: Date) => {
|
|
55
|
+
const adjusted = dateTime.makeZonedUnsafe(current, {
|
|
56
|
+
timeZone: zoned.zone,
|
|
57
|
+
- adjustForTimeZone: true
|
|
58
|
+
+ adjustForTimeZone: true,
|
|
59
|
+
+ disambiguation: reverse ? "later" : undefined
|
|
60
|
+
}).pipe(dateTime.toDate)
|
|
61
|
+
|
|
62
|
+
- // TODO: This implementation currently only skips forward when transitioning into daylight savings time.
|
|
63
|
+
const drift = current.getTime() - adjusted.getTime()
|
|
64
|
+
- if (drift > 0) {
|
|
65
|
+
- current.setTime(current.getTime() + drift)
|
|
66
|
+
+ if (reverse ? drift !== 0 : drift > 0) {
|
|
67
|
+
+ current.setTime(adjusted.getTime())
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const result = dateTime.mutate(zoned, (current) => {
|
|
72
|
+
- current.setUTCSeconds(current.getUTCSeconds() + 1, 0)
|
|
73
|
+
+ current.setUTCSeconds(current.getUTCSeconds() + tick, 0)
|
|
74
|
+
|
|
75
|
+
for (let i = 0; i < 10_000; i++) {
|
|
76
|
+
if (cron.seconds.size !== 0) {
|
|
77
|
+
const currentSecond = current.getUTCSeconds()
|
|
78
|
+
- const nextSecond = cron.next.second[currentSecond]
|
|
79
|
+
+ const nextSecond = table.second[currentSecond]
|
|
80
|
+
if (nextSecond === undefined) {
|
|
81
|
+
- current.setUTCMinutes(current.getUTCMinutes() + 1, cron.first.second)
|
|
82
|
+
+ current.setUTCMinutes(current.getUTCMinutes() + tick, boundary.second)
|
|
83
|
+
adjustDst(current)
|
|
84
|
+
continue
|
|
85
|
+
}
|
|
86
|
+
- if (nextSecond > currentSecond) {
|
|
87
|
+
+ if (needsStep(nextSecond, currentSecond)) {
|
|
88
|
+
current.setUTCSeconds(nextSecond)
|
|
89
|
+
adjustDst(current)
|
|
90
|
+
continue
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (cron.minutes.size !== 0) {
|
|
95
|
+
const currentMinute = current.getUTCMinutes()
|
|
96
|
+
- const nextMinute = cron.next.minute[currentMinute]
|
|
97
|
+
+ const nextMinute = table.minute[currentMinute]
|
|
98
|
+
if (nextMinute === undefined) {
|
|
99
|
+
- current.setUTCHours(current.getUTCHours() + 1, cron.first.minute, cron.first.second)
|
|
100
|
+
+ current.setUTCHours(current.getUTCHours() + tick, boundary.minute, boundary.second)
|
|
101
|
+
adjustDst(current)
|
|
102
|
+
continue
|
|
103
|
+
}
|
|
104
|
+
- if (nextMinute > currentMinute) {
|
|
105
|
+
- current.setUTCMinutes(nextMinute, cron.first.second)
|
|
106
|
+
+ if (needsStep(nextMinute, currentMinute)) {
|
|
107
|
+
+ current.setUTCMinutes(nextMinute, boundary.second)
|
|
108
|
+
adjustDst(current)
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (cron.hours.size !== 0) {
|
|
114
|
+
const currentHour = current.getUTCHours()
|
|
115
|
+
- const nextHour = cron.next.hour[currentHour]
|
|
116
|
+
+ const nextHour = table.hour[currentHour]
|
|
117
|
+
if (nextHour === undefined) {
|
|
118
|
+
- current.setUTCDate(current.getUTCDate() + 1)
|
|
119
|
+
- current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
|
|
120
|
+
+ current.setUTCDate(current.getUTCDate() + tick)
|
|
121
|
+
+ current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
|
|
122
|
+
adjustDst(current)
|
|
123
|
+
continue
|
|
124
|
+
}
|
|
125
|
+
- if (nextHour > currentHour) {
|
|
126
|
+
- current.setUTCHours(nextHour, cron.first.minute, cron.first.second)
|
|
127
|
+
+ if (needsStep(nextHour, currentHour)) {
|
|
128
|
+
+ current.setUTCHours(nextHour, boundary.minute, boundary.second)
|
|
129
|
+
adjustDst(current)
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (cron.weekdays.size !== 0 || cron.days.size !== 0) {
|
|
135
|
+
- let a: number = Infinity
|
|
136
|
+
- let b: number = Infinity
|
|
137
|
+
+ let a: number = reverse ? -Infinity : Infinity
|
|
138
|
+
+ let b: number = reverse ? -Infinity : Infinity
|
|
139
|
+
|
|
140
|
+
if (cron.weekdays.size !== 0) {
|
|
141
|
+
const currentWeekday = current.getUTCDay()
|
|
142
|
+
- const nextWeekday = cron.next.weekday[currentWeekday]
|
|
143
|
+
- a = nextWeekday === undefined ? 7 - currentWeekday + cron.first.weekday : nextWeekday - currentWeekday
|
|
144
|
+
+ const nextWeekday = table.weekday[currentWeekday]
|
|
145
|
+
+ if (nextWeekday === undefined) {
|
|
146
|
+
+ a = reverse ?
|
|
147
|
+
+ currentWeekday - 7 + boundary.weekday :
|
|
148
|
+
+ 7 - currentWeekday + boundary.weekday
|
|
149
|
+
+ } else {
|
|
150
|
+
+ a = nextWeekday - currentWeekday
|
|
151
|
+
+ }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (cron.days.size !== 0 && a !== 0) {
|
|
155
|
+
const currentDay = current.getUTCDate()
|
|
156
|
+
- const nextDay = cron.next.day[currentDay]
|
|
157
|
+
- b = nextDay === undefined ? daysInMonth(current) - currentDay + cron.first.day : nextDay - currentDay
|
|
158
|
+
+ const nextDay = table.day[currentDay]
|
|
159
|
+
+ if (nextDay === undefined) {
|
|
160
|
+
+ if (reverse) {
|
|
161
|
+
+ const prevMonthDays = daysInMonth(new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), 0)))
|
|
162
|
+
+ b = -(currentDay + (prevMonthDays - boundary.day))
|
|
163
|
+
+ } else {
|
|
164
|
+
+ b = daysInMonth(current) - currentDay + boundary.day
|
|
165
|
+
+ }
|
|
166
|
+
+ } else {
|
|
167
|
+
+ b = nextDay - currentDay
|
|
168
|
+
+ }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
- const addDays = Math.min(a, b)
|
|
172
|
+
+ const addDays = reverse ? Math.max(a, b) : Math.min(a, b)
|
|
173
|
+
if (addDays !== 0) {
|
|
174
|
+
current.setUTCDate(current.getUTCDate() + addDays)
|
|
175
|
+
- current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
|
|
176
|
+
+ current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
|
|
177
|
+
adjustDst(current)
|
|
178
|
+
continue
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (cron.months.size !== 0) {
|
|
183
|
+
const currentMonth = current.getUTCMonth() + 1
|
|
184
|
+
- const nextMonth = cron.next.month[currentMonth]
|
|
185
|
+
+ const nextMonth = table.month[currentMonth]
|
|
186
|
+
+ const clampBoundaryDay = (targetMonthIndex: number): number => {
|
|
187
|
+
+ if (cron.days.size !== 0) {
|
|
188
|
+
+ return boundary.day
|
|
189
|
+
+ }
|
|
190
|
+
+ const maxDayInMonth = daysInMonth(new Date(Date.UTC(current.getUTCFullYear(), targetMonthIndex + 1, 0)))
|
|
191
|
+
+ return Math.min(boundary.day, maxDayInMonth)
|
|
192
|
+
+ }
|
|
193
|
+
if (nextMonth === undefined) {
|
|
194
|
+
- current.setUTCFullYear(current.getUTCFullYear() + 1)
|
|
195
|
+
- current.setUTCMonth(cron.first.month, cron.first.day)
|
|
196
|
+
- current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
|
|
197
|
+
+ current.setUTCFullYear(current.getUTCFullYear() + tick)
|
|
198
|
+
+ current.setUTCMonth(boundary.month, clampBoundaryDay(boundary.month))
|
|
199
|
+
+ current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
|
|
200
|
+
adjustDst(current)
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
- if (nextMonth > currentMonth) {
|
|
204
|
+
- current.setUTCMonth(nextMonth - 1, cron.first.day)
|
|
205
|
+
- current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
|
|
206
|
+
+ if (needsStep(nextMonth, currentMonth)) {
|
|
207
|
+
+ const targetMonthIndex = nextMonth - 1
|
|
208
|
+
+ current.setUTCMonth(targetMonthIndex, clampBoundaryDay(targetMonthIndex))
|
|
209
|
+
+ current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
|
|
210
|
+
adjustDst(current)
|
|
211
|
+
continue
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
@@
|
|
215
|
+
- throw new Error("Unable to find next cron date")
|
|
216
|
+
+ throw new Error(\`Unable to find \${direction} cron date\`)
|
|
217
|
+
})
|
|
218
|
+
*** End Patch`
|
|
219
|
+
console.log(await applyPatch(patch))
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
await taskComplete(`Implemented backport of Cron reverse scheduling support.
|
|
2
|
+
|
|
3
|
+
### ✅ Changes made
|
|
4
|
+
- Added internal reverse lookup support to \\`Cron\\`:
|
|
5
|
+
- new internal \\`last\\` boundary values
|
|
6
|
+
- new internal \\`prev\\` lookup tables
|
|
7
|
+
- generalized lookup table builder for both directions
|
|
8
|
+
- Added new public APIs in \\`packages/effect/src/Cron.ts\\`:
|
|
9
|
+
- \\`Cron.prev(cron, now?)\\`
|
|
10
|
+
- \\`Cron.sequenceReverse(cron, now?)\\`
|
|
11
|
+
- Refactored \\`Cron.next\\` and \\`Cron.prev\\` to share core stepping logic via internal \\`stepCron\\`.
|
|
12
|
+
- Included DST-aware reverse stepping behavior (including fall-back disambiguation handling).
|
|
13
|
+
- Added test coverage in \\`packages/effect/test/Cron.test.ts\\` for:
|
|
14
|
+
- basic \\`prev\\` behavior
|
|
15
|
+
- \\`sequenceReverse\\`
|
|
16
|
+
- month/day edge cases (e.g. day 31 skipping shorter months)
|
|
17
|
+
- month-clamping behavior with month-only constraints
|
|
18
|
+
- DST fall-back reverse behavior
|
|
19
|
+
- Added changeset:
|
|
20
|
+
- \\`.changeset/backport-cron-prev.md\\` (
|
|
21
|
+
\\`"effect": minor\\`
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
### ✅ Validation run
|
|
25
|
+
- \\`pnpm lint-fix\\`
|
|
26
|
+
- \\`pnpm test packages/effect/test/Cron.test.ts\\`
|
|
27
|
+
- \\`pnpm check:tsgo\\`
|
|
28
|
+
- \\`pnpm docgen\\`
|
|
29
|
+
|
|
30
|
+
All completed successfully.`);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
await taskComplete(`Implemented backport of Cron reverse scheduling support.
|
|
2
|
+
|
|
3
|
+
### ✅ Changes made
|
|
4
|
+
- Added internal reverse lookup support to \`Cron\`:
|
|
5
|
+
- new internal \`last\` boundary values
|
|
6
|
+
- new internal \`prev\` lookup tables
|
|
7
|
+
- generalized lookup table builder for both directions
|
|
8
|
+
- Added new public APIs in \`packages/effect/src/Cron.ts\`:
|
|
9
|
+
- \`Cron.prev(cron, now?)\`
|
|
10
|
+
- \`Cron.sequenceReverse(cron, now?)\`
|
|
11
|
+
- Refactored \`Cron.next\` and \`Cron.prev\` to share core stepping logic via internal \`stepCron\`.
|
|
12
|
+
- Included DST-aware reverse stepping behavior (including fall-back disambiguation handling).
|
|
13
|
+
- Added test coverage in \`packages/effect/test/Cron.test.ts\` for:
|
|
14
|
+
- basic \`prev\` behavior
|
|
15
|
+
- \`sequenceReverse\`
|
|
16
|
+
- month/day edge cases (e.g. day 31 skipping shorter months)
|
|
17
|
+
- month-clamping behavior with month-only constraints
|
|
18
|
+
- DST fall-back reverse behavior
|
|
19
|
+
- Added changeset:
|
|
20
|
+
- \`.changeset/backport-cron-prev.md\` (
|
|
21
|
+
\`"effect": minor\`
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
### ✅ Validation run
|
|
25
|
+
- \`pnpm lint-fix\`
|
|
26
|
+
- \`pnpm test packages/effect/test/Cron.test.ts\`
|
|
27
|
+
- \`pnpm check:tsgo\`
|
|
28
|
+
- \`pnpm docgen\`
|
|
29
|
+
|
|
30
|
+
All completed successfully.`);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const tasks = await listTasks({});
|
|
2
|
+
const task = tasks.find((t) => t.id === 'EFF-738');
|
|
3
|
+
if (!task) throw new Error('Task EFF-738 not found');
|
|
4
|
+
const addition = `\n\nDiscovery update:\n\n* Archived regression tests are in \\.repos/effect-old/packages/effect/test/Cron.test.ts (not Cron.ts) and include extensive \\`prev\\` + \\`sequenceReverse\\` coverage that maps cleanly to current APIs by renaming \\`unsafeParse\\` -> \\`parseUnsafe\\` and DateTime helpers to \\`zoneMakeNamedUnsafe\\` / \\`makeZonedUnsafe\\`.\n* Old \\`prev\\` implementation depends on internal cron metadata additions: \\`last\\` boundaries + reverse lookup tables \\`prev\\`; these need to be added to current \\`Cron.make\\` output before implementing reverse stepping.`;
|
|
5
|
+
await updateTask({
|
|
6
|
+
taskId: 'EFF-738',
|
|
7
|
+
description: task.description + addition,
|
|
8
|
+
state: 'in-progress'
|
|
9
|
+
});
|
|
10
|
+
console.log('updated task');
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const tasks = await listTasks({});
|
|
2
|
+
const task = tasks.find((t) => t.id === 'EFF-738');
|
|
3
|
+
if (!task) throw new Error('Task EFF-738 not found');
|
|
4
|
+
const addition = `\n\nDiscovery update:\n\n* Archived regression tests are in .repos/effect-old/packages/effect/test/Cron.test.ts (not Cron.ts) and include extensive \`prev\` + \`sequenceReverse\` coverage that maps cleanly to current APIs by renaming \`unsafeParse\` -> \`parseUnsafe\` and DateTime helpers to \`zoneMakeNamedUnsafe\` / \`makeZonedUnsafe\`.\n* Old \`prev\` implementation depends on internal cron metadata additions: \`last\` boundaries + reverse lookup tables \`prev\`; these need to be added to current \`Cron.make\` output before implementing reverse stepping.`;
|
|
5
|
+
await updateTask({
|
|
6
|
+
taskId: 'EFF-738',
|
|
7
|
+
description: task.description + addition,
|
|
8
|
+
state: 'in-progress'
|
|
9
|
+
});
|
|
10
|
+
console.log('updated task');
|