cronli5 0.2.0 → 0.3.1

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 (57) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +4 -4
  3. package/cronli5.min.js +2 -2
  4. package/dist/cronli5.cjs +514 -407
  5. package/dist/cronli5.js +514 -407
  6. package/dist/lang/de.cjs +296 -225
  7. package/dist/lang/de.js +296 -225
  8. package/dist/lang/en.cjs +471 -364
  9. package/dist/lang/en.js +471 -364
  10. package/dist/lang/es.cjs +318 -281
  11. package/dist/lang/es.js +318 -281
  12. package/dist/lang/fi.cjs +326 -276
  13. package/dist/lang/fi.js +326 -276
  14. package/dist/lang/zh.cjs +308 -236
  15. package/dist/lang/zh.js +308 -236
  16. package/package.json +1 -1
  17. package/src/core/analyze.ts +22 -21
  18. package/src/core/cadence.ts +164 -0
  19. package/src/core/index.ts +3 -1
  20. package/src/core/normalize.ts +3 -3
  21. package/src/core/parse.ts +1 -1
  22. package/src/core/{ir.ts → schedule.ts} +23 -24
  23. package/src/core/shapes.ts +8 -1
  24. package/src/core/specs.ts +1 -1
  25. package/src/core/util.ts +4 -83
  26. package/src/core/validate.ts +2 -2
  27. package/src/core/weekday.ts +54 -0
  28. package/src/cronli5.ts +7 -7
  29. package/src/lang/de/index.ts +329 -288
  30. package/src/lang/en/dialects.ts +1 -1
  31. package/src/lang/en/index.ts +640 -516
  32. package/src/lang/es/index.ts +342 -374
  33. package/src/lang/es/notes.md +1 -1
  34. package/src/lang/fi/dialects.ts +1 -1
  35. package/src/lang/fi/index.ts +367 -372
  36. package/src/lang/fi/notes.md +23 -8
  37. package/src/lang/fi/status.json +1 -1
  38. package/src/lang/zh/index.ts +344 -262
  39. package/src/types.ts +6 -6
  40. package/types/core/analyze.d.ts +4 -4
  41. package/types/core/cadence.d.ts +33 -0
  42. package/types/core/index.d.ts +3 -1
  43. package/types/core/normalize.d.ts +1 -1
  44. package/types/core/parse.d.ts +1 -1
  45. package/types/core/{ir.d.ts → schedule.d.ts} +16 -21
  46. package/types/core/shapes.d.ts +2 -1
  47. package/types/core/specs.d.ts +1 -1
  48. package/types/core/util.d.ts +1 -15
  49. package/types/core/weekday.d.ts +10 -0
  50. package/types/lang/de/index.d.ts +1 -1
  51. package/types/lang/en/dialects.d.ts +1 -1
  52. package/types/lang/en/index.d.ts +1 -1
  53. package/types/lang/es/index.d.ts +1 -1
  54. package/types/lang/fi/dialects.d.ts +1 -1
  55. package/types/lang/fi/index.d.ts +1 -1
  56. package/types/lang/zh/index.d.ts +1 -1
  57. package/types/types.d.ts +5 -5
package/src/types.ts CHANGED
@@ -46,22 +46,22 @@ export interface Cronli5Dialect {
46
46
  }
47
47
 
48
48
  /**
49
- * A language module is a renderer over the semantic IR plus the
49
+ * A language module is a renderer over the semantic Schedule plus the
50
50
  * language-owned strings and option normalization. The `describe`/`options`
51
- * payloads are the module's internal `IR`/options shapes (see
52
- * `core/ir.ts`). They are intentionally opaque at this public boundary,
51
+ * payloads are the module's internal `Schedule`/options shapes (see
52
+ * `core/schedule.ts`). They are intentionally opaque at this public boundary,
53
53
  * which a caller passes to `cronli5` via the `lang` option but never invokes
54
54
  * directly.
55
55
  */
56
56
  export interface Cronli5Language {
57
- describe(ir: any, opts: any): string;
57
+ describe(schedule: any, opts: any): string;
58
58
  fallback: string;
59
59
  options(options?: Cronli5Options): any;
60
60
  reboot: string;
61
61
  sentence(description: string): string;
62
- // Optional strategy override (see `core/ir.ts` `Language.strategy`). Opaque
62
+ // Optional plan override (see `core/schedule.ts` `Language.plan`). Opaque
63
63
  // at this public boundary, like `describe`/`options`.
64
- strategy?(content: any, base: any): any;
64
+ plan?(facts: any, base: any): any;
65
65
  }
66
66
 
67
67
  /**
@@ -1,4 +1,4 @@
1
- import type { Content, IR, Pattern, PlanNode } from './ir.js';
1
+ import type { Pattern, PlanNode, Schedule, ScheduleFacts } from './schedule.js';
2
2
  declare function getOccurrences(start: number, interval: number, max: number): number[];
3
3
  declare function enumerateStep(field: string, min: number, max: number, numberMap?: {
4
4
  [name: string]: number;
@@ -8,6 +8,6 @@ declare function enumerateValues(field: string): number[];
8
8
  declare function minuteSpan(minuteField: string): [number, number] | null;
9
9
  declare function lastMinuteFire(minuteField: string): number;
10
10
  declare function clockSecond(secondField: string): number | undefined;
11
- declare function analyze(pattern: Pattern): IR;
12
- declare function selectStrategy(content: Content): PlanNode;
13
- export { analyze, clockSecond, enumerateFires, enumerateStep, enumerateValues, getOccurrences, lastMinuteFire, minuteSpan, selectStrategy };
11
+ declare function analyze(pattern: Pattern): Schedule;
12
+ declare function selectPlan(facts: ScheduleFacts): PlanNode;
13
+ export { analyze, clockSecond, enumerateFires, enumerateStep, enumerateValues, getOccurrences, lastMinuteFire, minuteSpan, selectPlan };
@@ -0,0 +1,33 @@
1
+ import type { Field, Schedule, Segment } from './schedule.js';
2
+ type StepSegment = Extract<Segment, {
3
+ kind: 'step';
4
+ }>;
5
+ declare function arithmeticStep(values: number[]): {
6
+ start: number;
7
+ interval: number;
8
+ last: number;
9
+ } | null;
10
+ declare function segmentsOf(schedule: Schedule, field: Field): Segment[];
11
+ declare function stepSegment(schedule: Schedule, field: Field): StepSegment;
12
+ declare function singleValues(segments: Segment[]): number[] | null;
13
+ declare function offsetCleanStride(stride: {
14
+ start: number;
15
+ interval: number;
16
+ }): boolean;
17
+ interface StrideParts {
18
+ bare(): string;
19
+ offset(): string;
20
+ bounded(): string;
21
+ }
22
+ declare function renderStride(spec: {
23
+ start: number;
24
+ interval: number;
25
+ cycle: number;
26
+ }, parts: StrideParts): string;
27
+ declare function hourListStride(values: number[]): {
28
+ start: number;
29
+ interval: number;
30
+ last: number;
31
+ } | null;
32
+ export { arithmeticStep, hourListStride, offsetCleanStride, renderStride, segmentsOf, singleValues, stepSegment };
33
+ export type { StrideParts };
@@ -1,8 +1,10 @@
1
- import type { NormalizedOptions, Pattern } from './ir.js';
1
+ import type { NormalizedOptions, Pattern } from './schedule.js';
2
2
  import type { CronPattern } from '../types.js';
3
3
  declare function prepare(cronPattern: CronPattern, opts: NormalizedOptions): Pattern;
4
4
  export { prepare };
5
5
  export * from './specs.js';
6
6
  export * from './util.js';
7
+ export * from './weekday.js';
8
+ export * from './cadence.js';
7
9
  export * from './shapes.js';
8
10
  export * from './analyze.js';
@@ -1,5 +1,5 @@
1
1
  import type { CronLike } from './specs.js';
2
- import type { Pattern } from './ir.js';
2
+ import type { Pattern } from './schedule.js';
3
3
  declare function applyQuartzAliases(cronPattern: CronLike): void;
4
4
  declare function normalizeCronPattern(cronPattern: CronLike): Pattern;
5
5
  export { applyQuartzAliases, normalizeCronPattern };
@@ -1,5 +1,5 @@
1
1
  import type { CronLike } from './specs.js';
2
- import type { NormalizedOptions } from './ir.js';
2
+ import type { NormalizedOptions } from './schedule.js';
3
3
  import type { CronPattern } from '../types.js';
4
4
  declare function parseCronPattern(cronPattern: CronPattern, opts: NormalizedOptions): CronLike;
5
5
  export { parseCronPattern };
@@ -43,11 +43,6 @@ export type HoursPlan = {
43
43
  } | {
44
44
  kind: 'during';
45
45
  times: HourTimesPlan;
46
- } | {
47
- kind: 'single';
48
- from: number;
49
- to: number;
50
- last: number;
51
46
  };
52
47
  /** Hour times: enumerated fires, or deferred to per-segment rendering. */
53
48
  export type HourTimesPlan = {
@@ -57,7 +52,7 @@ export type HourTimesPlan = {
57
52
  kind: 'segments';
58
53
  };
59
54
  /**
60
- * The rendering strategy the core selects for a pattern. The `kind`
55
+ * The rendering plan the core selects for a pattern. The `kind`
61
56
  * discriminant tells a renderer which fields are present.
62
57
  */
63
58
  export type PlanNode = {
@@ -121,25 +116,25 @@ export interface Analyses {
121
116
  segments: Record<Field, Segment[] | null>;
122
117
  }
123
118
  /**
124
- * The neutral content plan: the language-independent facts about a pattern,
125
- * carrying no phrasing decision. `analyze` produces this; `selectStrategy`
126
- * reads it to suggest a `plan`. The phrasing strategy is deliberately *not*
127
- * part of the neutral content (docs/i18n-design.md §2.2).
119
+ * The neutral schedule facts: the language-independent facts about a pattern,
120
+ * carrying no phrasing decision. `analyze` produces this; `selectPlan`
121
+ * reads it to suggest a `plan`. The phrasing plan is deliberately *not*
122
+ * part of the neutral facts (docs/i18n-design.md §2.2).
128
123
  */
129
- export interface Content {
124
+ export interface ScheduleFacts {
130
125
  pattern: Pattern;
131
126
  shapes: Shapes;
132
127
  analyses: Analyses;
133
128
  }
134
129
  /**
135
- * The semantic intermediate representation a language renders: the neutral
136
- * `Content` plus the selected `plan`. A language may widen `plan` with its
137
- * own `Extra` strategy kinds via `Language.strategy`; by default there are
138
- * none, so `IR` is the neutral content with a core `PlanNode`.
130
+ * The semantic schedule a language renders: the neutral `ScheduleFacts`
131
+ * plus the selected `plan`. A language may widen `plan` with its own
132
+ * `Extra` plan kinds via `Language.plan`; by default there are none, so
133
+ * `Schedule` is the neutral facts with a core `PlanNode`.
139
134
  */
140
- export interface IR<Extra extends {
135
+ export interface Schedule<Extra extends {
141
136
  kind: string;
142
- } = never> extends Content {
137
+ } = never> extends ScheduleFacts {
143
138
  plan: PlanNode | Extra;
144
139
  }
145
140
  /** A resolved style table. */
@@ -172,16 +167,16 @@ export interface NormalizedOptions<Style = DialectStyle> {
172
167
  }
173
168
  /**
174
169
  * The interface every language module's default export implements. `Extra`
175
- * lets a language add its own strategy kinds (default: none), which its
176
- * `strategy` override emits and its `describe` renders.
170
+ * lets a language add its own plan kinds (default: none), which its
171
+ * `plan` override emits and its `describe` renders.
177
172
  */
178
173
  export interface Language<Style = DialectStyle, Extra extends {
179
174
  kind: string;
180
175
  } = never> {
181
- describe(ir: IR<Extra>, opts: NormalizedOptions<Style>): string;
176
+ describe(schedule: Schedule<Extra>, opts: NormalizedOptions<Style>): string;
182
177
  fallback: string;
183
178
  options(options?: Cronli5Options): NormalizedOptions<Style>;
184
179
  reboot: string;
185
180
  sentence(description: string): string;
186
- strategy?(content: Content, base: PlanNode): PlanNode | Extra;
181
+ plan?(facts: ScheduleFacts, base: PlanNode): PlanNode | Extra;
187
182
  }
@@ -3,4 +3,5 @@ declare function isPlainRange(field: string): boolean;
3
3
  declare function isPlainStep(field: string): boolean;
4
4
  declare function isDiscreteList(field: string): boolean;
5
5
  declare function isDiscreteHours(hourField: string): boolean;
6
- export { isDiscreteHours, isDiscreteList, isPlainRange, isPlainStep, isSingleValue };
6
+ declare function isOpenStep(field: string): boolean;
7
+ export { isDiscreteHours, isDiscreteList, isOpenStep, isPlainRange, isPlainStep, isSingleValue };
@@ -1,4 +1,4 @@
1
- import type { Field } from './ir.js';
1
+ import type { Field } from './schedule.js';
2
2
  /**
3
3
  * A parsed but not-yet-canonical cron pattern: every field present, values
4
4
  * still as the caller gave them (string or number) until normalization
@@ -1,21 +1,7 @@
1
- import type { Segment } from './ir.js';
2
1
  declare function includes(str: string | number, sub: string): boolean;
3
2
  declare function unique<T>(items: T[]): T[];
4
3
  declare function isNonNegativeInteger(value: string): boolean;
5
- declare function arithmeticStep(values: number[]): {
6
- start: number;
7
- interval: number;
8
- last: number;
9
- } | null;
10
- type WeekdaySegment = {
11
- kind: 'single';
12
- value: string;
13
- } | {
14
- kind: 'range';
15
- bounds: [string, string];
16
- };
17
- declare function orderWeekdaysForDisplay(segments: Segment[]): WeekdaySegment[];
18
4
  declare function toFieldNumber(token: string, numberMap?: {
19
5
  [name: string]: number;
20
6
  }): number;
21
- export { arithmeticStep, includes, isNonNegativeInteger, orderWeekdaysForDisplay, toFieldNumber, unique };
7
+ export { includes, isNonNegativeInteger, toFieldNumber, unique };
@@ -0,0 +1,10 @@
1
+ import type { Segment } from './schedule.js';
2
+ type WeekdaySegment = {
3
+ kind: 'single';
4
+ value: string;
5
+ } | {
6
+ kind: 'range';
7
+ bounds: [string, string];
8
+ };
9
+ declare function orderWeekdaysForDisplay(segments: Segment[]): WeekdaySegment[];
10
+ export { orderWeekdaysForDisplay };
@@ -1,4 +1,4 @@
1
- import type { Language } from '../../core/ir.js';
1
+ import type { Language } from '../../core/schedule.js';
2
2
  import { type GermanStyle } from './dialects.js';
3
3
  declare const de: Language<GermanStyle>;
4
4
  export default de;
@@ -1,4 +1,4 @@
1
1
  import type { Cronli5Options } from '../../types.js';
2
- import type { DialectStyle } from '../../core/ir.js';
2
+ import type { DialectStyle } from '../../core/schedule.js';
3
3
  declare function resolveDialect(dialect?: Cronli5Options['dialect']): DialectStyle;
4
4
  export { resolveDialect };
@@ -1,3 +1,3 @@
1
- import type { Language } from '../../core/ir.js';
1
+ import type { Language } from '../../core/schedule.js';
2
2
  declare const en: Language;
3
3
  export default en;
@@ -1,4 +1,4 @@
1
- import type { Language } from '../../core/ir.js';
1
+ import type { Language } from '../../core/schedule.js';
2
2
  import { type SpanishStyle } from './dialects.js';
3
3
  declare const es: Language<SpanishStyle>;
4
4
  export default es;
@@ -1,4 +1,4 @@
1
- import type { DialectStyle } from '../../core/ir.js';
1
+ import type { DialectStyle } from '../../core/schedule.js';
2
2
  import type { Cronli5Options } from '../../types.js';
3
3
  declare function resolveDialect(dialect?: Cronli5Options['dialect']): DialectStyle;
4
4
  export { resolveDialect };
@@ -1,3 +1,3 @@
1
- import type { Language } from '../../core/ir.js';
1
+ import type { Language } from '../../core/schedule.js';
2
2
  declare const fi: Language;
3
3
  export default fi;
@@ -1,4 +1,4 @@
1
- import type { Language } from '../../core/ir.js';
1
+ import type { Language } from '../../core/schedule.js';
2
2
  import { type ChineseStyle } from './dialects.js';
3
3
  declare const zh: Language<ChineseStyle>;
4
4
  export default zh;
package/types/types.d.ts CHANGED
@@ -30,20 +30,20 @@ export interface Cronli5Dialect {
30
30
  through?: string;
31
31
  }
32
32
  /**
33
- * A language module is a renderer over the semantic IR plus the
33
+ * A language module is a renderer over the semantic Schedule plus the
34
34
  * language-owned strings and option normalization. The `describe`/`options`
35
- * payloads are the module's internal `IR`/options shapes (see
36
- * `core/ir.ts`). They are intentionally opaque at this public boundary,
35
+ * payloads are the module's internal `Schedule`/options shapes (see
36
+ * `core/schedule.ts`). They are intentionally opaque at this public boundary,
37
37
  * which a caller passes to `cronli5` via the `lang` option but never invokes
38
38
  * directly.
39
39
  */
40
40
  export interface Cronli5Language {
41
- describe(ir: any, opts: any): string;
41
+ describe(schedule: any, opts: any): string;
42
42
  fallback: string;
43
43
  options(options?: Cronli5Options): any;
44
44
  reboot: string;
45
45
  sentence(description: string): string;
46
- strategy?(content: any, base: any): any;
46
+ plan?(facts: any, base: any): any;
47
47
  }
48
48
  /**
49
49
  * Option flags accepted as the second argument to `cronli5`.