@chkit/plugin-backfill 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/args.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { ParsedCancelArgs, ParsedDoctorArgs, ParsedPlanArgs, ParsedResumeArgs, ParsedRunArgs, ParsedStatusArgs } from './types.js';
2
+ export declare function parsePlanArgs(args: string[]): ParsedPlanArgs;
3
+ export declare function parseRunArgs(args: string[]): ParsedRunArgs;
4
+ export declare function parseResumeArgs(args: string[]): ParsedResumeArgs;
5
+ export declare function parseStatusArgs(args: string[]): ParsedStatusArgs;
6
+ export declare function parseCancelArgs(args: string[]): ParsedCancelArgs;
7
+ export declare function parseDoctorArgs(args: string[]): ParsedDoctorArgs;
8
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAgCnB,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAgD5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAoE1D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAShE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAkBhE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAEhE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAEhE"}
package/dist/args.js ADDED
@@ -0,0 +1,170 @@
1
+ import { BackfillConfigError } from './errors.js';
2
+ function normalizeTimestamp(raw, flagName) {
3
+ const value = raw.trim();
4
+ if (value.length === 0) {
5
+ throw new BackfillConfigError(`Missing value for ${flagName}`);
6
+ }
7
+ const date = new Date(value);
8
+ if (Number.isNaN(date.getTime())) {
9
+ throw new BackfillConfigError(`Invalid timestamp for ${flagName}: ${raw}`);
10
+ }
11
+ return date.toISOString();
12
+ }
13
+ function normalizeTarget(raw) {
14
+ const value = raw.trim();
15
+ if (!/^[A-Za-z0-9_]+\.[A-Za-z0-9_]+$/.test(value)) {
16
+ throw new BackfillConfigError('Invalid value for --target. Expected <database.table>.');
17
+ }
18
+ return value;
19
+ }
20
+ function normalizePlanId(raw) {
21
+ const value = raw.trim();
22
+ if (!/^[a-f0-9]{16}$/.test(value)) {
23
+ throw new BackfillConfigError('Invalid value for --plan-id. Expected a 16-char lowercase hex id.');
24
+ }
25
+ return value;
26
+ }
27
+ export function parsePlanArgs(args) {
28
+ let target;
29
+ let from;
30
+ let to;
31
+ let chunkHours;
32
+ let forceLargeWindow = false;
33
+ for (let i = 0; i < args.length; i += 1) {
34
+ const token = args[i];
35
+ if (!token)
36
+ continue;
37
+ if (token === '--force-large-window') {
38
+ forceLargeWindow = true;
39
+ continue;
40
+ }
41
+ if (token === '--target' || token === '--from' || token === '--to' || token === '--chunk-hours') {
42
+ const nextValue = args[i + 1];
43
+ if (!nextValue || nextValue.startsWith('--')) {
44
+ throw new BackfillConfigError(`Missing value for ${token}`);
45
+ }
46
+ if (token === '--target')
47
+ target = nextValue;
48
+ if (token === '--from')
49
+ from = nextValue;
50
+ if (token === '--to')
51
+ to = nextValue;
52
+ if (token === '--chunk-hours') {
53
+ const parsed = Number(nextValue);
54
+ if (!Number.isFinite(parsed) || parsed <= 0) {
55
+ throw new BackfillConfigError('Invalid value for --chunk-hours. Expected a positive number.');
56
+ }
57
+ chunkHours = parsed;
58
+ }
59
+ i += 1;
60
+ }
61
+ }
62
+ if (!target)
63
+ throw new BackfillConfigError('Missing required --target <database.table>');
64
+ if (!from)
65
+ throw new BackfillConfigError('Missing required --from <timestamp>');
66
+ if (!to)
67
+ throw new BackfillConfigError('Missing required --to <timestamp>');
68
+ return {
69
+ target: normalizeTarget(target),
70
+ from: normalizeTimestamp(from, '--from'),
71
+ to: normalizeTimestamp(to, '--to'),
72
+ chunkHours,
73
+ forceLargeWindow,
74
+ };
75
+ }
76
+ export function parseRunArgs(args) {
77
+ let planId;
78
+ let replayDone = false;
79
+ let replayFailed = false;
80
+ let forceOverlap = false;
81
+ let forceCompatibility = false;
82
+ let simulateFailChunk;
83
+ let simulateFailCount = 1;
84
+ for (let i = 0; i < args.length; i += 1) {
85
+ const token = args[i];
86
+ if (!token)
87
+ continue;
88
+ if (token === '--replay-done') {
89
+ replayDone = true;
90
+ continue;
91
+ }
92
+ if (token === '--replay-failed') {
93
+ replayFailed = true;
94
+ continue;
95
+ }
96
+ if (token === '--force-overlap') {
97
+ forceOverlap = true;
98
+ continue;
99
+ }
100
+ if (token === '--force-compatibility') {
101
+ forceCompatibility = true;
102
+ continue;
103
+ }
104
+ if (token === '--plan-id' ||
105
+ token === '--simulate-fail-chunk' ||
106
+ token === '--simulate-fail-count') {
107
+ const nextValue = args[i + 1];
108
+ if (!nextValue || nextValue.startsWith('--')) {
109
+ throw new BackfillConfigError(`Missing value for ${token}`);
110
+ }
111
+ if (token === '--plan-id')
112
+ planId = nextValue;
113
+ if (token === '--simulate-fail-chunk')
114
+ simulateFailChunk = nextValue;
115
+ if (token === '--simulate-fail-count') {
116
+ const parsed = Number(nextValue);
117
+ if (!Number.isFinite(parsed) || parsed <= 0 || !Number.isInteger(parsed)) {
118
+ throw new BackfillConfigError('Invalid value for --simulate-fail-count. Expected integer > 0.');
119
+ }
120
+ simulateFailCount = parsed;
121
+ }
122
+ i += 1;
123
+ }
124
+ }
125
+ if (!planId)
126
+ throw new BackfillConfigError('Missing required --plan-id <id>');
127
+ return {
128
+ planId: normalizePlanId(planId),
129
+ replayDone,
130
+ replayFailed,
131
+ forceOverlap,
132
+ forceCompatibility,
133
+ simulateFailChunk,
134
+ simulateFailCount,
135
+ };
136
+ }
137
+ export function parseResumeArgs(args) {
138
+ const parsed = parseRunArgs(args);
139
+ return {
140
+ planId: parsed.planId,
141
+ replayDone: parsed.replayDone,
142
+ replayFailed: parsed.replayFailed,
143
+ forceOverlap: parsed.forceOverlap,
144
+ forceCompatibility: parsed.forceCompatibility,
145
+ };
146
+ }
147
+ export function parseStatusArgs(args) {
148
+ let planId;
149
+ for (let i = 0; i < args.length; i += 1) {
150
+ const token = args[i];
151
+ if (token !== '--plan-id')
152
+ continue;
153
+ const nextValue = args[i + 1];
154
+ if (!nextValue || nextValue.startsWith('--')) {
155
+ throw new BackfillConfigError('Missing value for --plan-id');
156
+ }
157
+ planId = nextValue;
158
+ i += 1;
159
+ }
160
+ if (!planId)
161
+ throw new BackfillConfigError('Missing required --plan-id <id>');
162
+ return { planId: normalizePlanId(planId) };
163
+ }
164
+ export function parseCancelArgs(args) {
165
+ return parseStatusArgs(args);
166
+ }
167
+ export function parseDoctorArgs(args) {
168
+ return parseStatusArgs(args);
169
+ }
170
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAUjD,SAAS,kBAAkB,CAAC,GAAW,EAAE,QAAgB;IACvD,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IACxB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,mBAAmB,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,mBAAmB,CAAC,yBAAyB,QAAQ,KAAK,GAAG,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,OAAO,IAAI,CAAC,WAAW,EAAE,CAAA;AAC3B,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IACxB,IAAI,CAAC,gCAAgC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,mBAAmB,CAAC,wDAAwD,CAAC,CAAA;IACzF,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IACxB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,mBAAmB,CAAC,mEAAmE,CAAC,CAAA;IACpG,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,IAAI,MAA0B,CAAA;IAC9B,IAAI,IAAwB,CAAA;IAC5B,IAAI,EAAsB,CAAA;IAC1B,IAAI,UAA8B,CAAA;IAClC,IAAI,gBAAgB,GAAG,KAAK,CAAA;IAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACrB,IAAI,CAAC,KAAK;YAAE,SAAQ;QAEpB,IAAI,KAAK,KAAK,sBAAsB,EAAE,CAAC;YACrC,gBAAgB,GAAG,IAAI,CAAA;YACvB,SAAQ;QACV,CAAC;QAED,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,eAAe,EAAE,CAAC;YAChG,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7B,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,mBAAmB,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAA;YAC7D,CAAC;YAED,IAAI,KAAK,KAAK,UAAU;gBAAE,MAAM,GAAG,SAAS,CAAA;YAC5C,IAAI,KAAK,KAAK,QAAQ;gBAAE,IAAI,GAAG,SAAS,CAAA;YACxC,IAAI,KAAK,KAAK,MAAM;gBAAE,EAAE,GAAG,SAAS,CAAA;YACpC,IAAI,KAAK,KAAK,eAAe,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;gBAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;oBAC5C,MAAM,IAAI,mBAAmB,CAAC,8DAA8D,CAAC,CAAA;gBAC/F,CAAC;gBACD,UAAU,GAAG,MAAM,CAAA;YACrB,CAAC;YAED,CAAC,IAAI,CAAC,CAAA;QACR,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,mBAAmB,CAAC,4CAA4C,CAAC,CAAA;IACxF,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,mBAAmB,CAAC,qCAAqC,CAAC,CAAA;IAC/E,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,mBAAmB,CAAC,mCAAmC,CAAC,CAAA;IAE3E,OAAO;QACL,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;QAC/B,IAAI,EAAE,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC;QACxC,EAAE,EAAE,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC;QAClC,UAAU;QACV,gBAAgB;KACjB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,IAAI,MAA0B,CAAA;IAC9B,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,IAAI,YAAY,GAAG,KAAK,CAAA;IACxB,IAAI,YAAY,GAAG,KAAK,CAAA;IACxB,IAAI,kBAAkB,GAAG,KAAK,CAAA;IAC9B,IAAI,iBAAqC,CAAA;IACzC,IAAI,iBAAiB,GAAG,CAAC,CAAA;IAEzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACrB,IAAI,CAAC,KAAK;YAAE,SAAQ;QAEpB,IAAI,KAAK,KAAK,eAAe,EAAE,CAAC;YAC9B,UAAU,GAAG,IAAI,CAAA;YACjB,SAAQ;QACV,CAAC;QAED,IAAI,KAAK,KAAK,iBAAiB,EAAE,CAAC;YAChC,YAAY,GAAG,IAAI,CAAA;YACnB,SAAQ;QACV,CAAC;QAED,IAAI,KAAK,KAAK,iBAAiB,EAAE,CAAC;YAChC,YAAY,GAAG,IAAI,CAAA;YACnB,SAAQ;QACV,CAAC;QAED,IAAI,KAAK,KAAK,uBAAuB,EAAE,CAAC;YACtC,kBAAkB,GAAG,IAAI,CAAA;YACzB,SAAQ;QACV,CAAC;QAED,IACE,KAAK,KAAK,WAAW;YACrB,KAAK,KAAK,uBAAuB;YACjC,KAAK,KAAK,uBAAuB,EACjC,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7B,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,mBAAmB,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAA;YAC7D,CAAC;YAED,IAAI,KAAK,KAAK,WAAW;gBAAE,MAAM,GAAG,SAAS,CAAA;YAC7C,IAAI,KAAK,KAAK,uBAAuB;gBAAE,iBAAiB,GAAG,SAAS,CAAA;YACpE,IAAI,KAAK,KAAK,uBAAuB,EAAE,CAAC;gBACtC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;gBAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;oBACzE,MAAM,IAAI,mBAAmB,CAAC,gEAAgE,CAAC,CAAA;gBACjG,CAAC;gBACD,iBAAiB,GAAG,MAAM,CAAA;YAC5B,CAAC;YAED,CAAC,IAAI,CAAC,CAAA;QACR,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,mBAAmB,CAAC,iCAAiC,CAAC,CAAA;IAE7E,OAAO;QACL,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;QAC/B,UAAU;QACV,YAAY;QACZ,YAAY;QACZ,kBAAkB;QAClB,iBAAiB;QACjB,iBAAiB;KAClB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAc;IAC5C,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACjC,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;KAC9C,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAc;IAC5C,IAAI,MAA0B,CAAA;IAE9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACrB,IAAI,KAAK,KAAK,WAAW;YAAE,SAAQ;QAEnC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC7B,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,mBAAmB,CAAC,6BAA6B,CAAC,CAAA;QAC9D,CAAC;QACD,MAAM,GAAG,SAAS,CAAA;QAClB,CAAC,IAAI,CAAC,CAAA;IACR,CAAC;IAED,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,mBAAmB,CAAC,iCAAiC,CAAC,CAAA;IAE7E,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAc;IAC5C,OAAO,eAAe,CAAC,IAAI,CAAC,CAAA;AAC9B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAc;IAC5C,OAAO,eAAe,CAAC,IAAI,CAAC,CAAA;AAC9B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare class BackfillConfigError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B"}
package/dist/errors.js ADDED
@@ -0,0 +1,7 @@
1
+ export class BackfillConfigError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'BackfillConfigError';
5
+ }
6
+ }
7
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export { backfill, createBackfillPlugin } from './plugin.js';
2
+ export type { BackfillPlugin, BackfillPluginOptions, BackfillPluginRegistration } from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { backfill, createBackfillPlugin } from './plugin.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { BackfillPluginOptions, NormalizedBackfillPluginOptions } from './types.js';
2
+ export declare function normalizeBackfillOptions(options?: BackfillPluginOptions): NormalizedBackfillPluginOptions;
3
+ export declare function mergeOptions(baseOptions: NormalizedBackfillPluginOptions, runtimeOptions: Record<string, unknown>): NormalizedBackfillPluginOptions;
4
+ export declare function validateBaseOptions(options: NormalizedBackfillPluginOptions): void;
5
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAA;AAiHxF,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,qBAA0B,GAClC,+BAA+B,CAgBjC;AAED,wBAAgB,YAAY,CAC1B,WAAW,EAAE,+BAA+B,EAC5C,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACtC,+BAA+B,CAiBjC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,+BAA+B,GAAG,IAAI,CAMlF"}
@@ -0,0 +1,125 @@
1
+ import { BackfillConfigError } from './errors.js';
2
+ const DEFAULT_OPTIONS = {
3
+ defaults: {
4
+ chunkHours: 6,
5
+ maxParallelChunks: 1,
6
+ maxRetriesPerChunk: 3,
7
+ requireIdempotencyToken: true,
8
+ },
9
+ policy: {
10
+ requireDryRunBeforeRun: true,
11
+ requireExplicitWindow: true,
12
+ blockOverlappingRuns: true,
13
+ failCheckOnRequiredPendingBackfill: true,
14
+ },
15
+ limits: {
16
+ maxWindowHours: 24 * 30,
17
+ minChunkMinutes: 15,
18
+ },
19
+ };
20
+ function isRecord(value) {
21
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
22
+ }
23
+ function parsePositiveNumber(value, key) {
24
+ if (value === undefined)
25
+ return undefined;
26
+ if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
27
+ throw new BackfillConfigError(`Invalid plugin option "${key}". Expected a positive number.`);
28
+ }
29
+ return value;
30
+ }
31
+ function parseBoolean(value, key) {
32
+ if (value === undefined)
33
+ return undefined;
34
+ if (typeof value !== 'boolean') {
35
+ throw new BackfillConfigError(`Invalid plugin option "${key}". Expected boolean.`);
36
+ }
37
+ return value;
38
+ }
39
+ function parseString(value, key) {
40
+ if (value === undefined)
41
+ return undefined;
42
+ if (typeof value !== 'string' || value.trim().length === 0) {
43
+ throw new BackfillConfigError(`Invalid plugin option "${key}". Expected non-empty string.`);
44
+ }
45
+ return value;
46
+ }
47
+ function normalizeRuntimeOptions(options) {
48
+ const normalized = {};
49
+ const stateDir = parseString(options.stateDir, 'stateDir');
50
+ if (stateDir !== undefined)
51
+ normalized.stateDir = stateDir;
52
+ if (options.defaults !== undefined) {
53
+ if (!isRecord(options.defaults)) {
54
+ throw new BackfillConfigError('Invalid plugin option "defaults". Expected object.');
55
+ }
56
+ normalized.defaults = {
57
+ chunkHours: parsePositiveNumber(options.defaults.chunkHours, 'defaults.chunkHours'),
58
+ maxParallelChunks: parsePositiveNumber(options.defaults.maxParallelChunks, 'defaults.maxParallelChunks'),
59
+ maxRetriesPerChunk: parsePositiveNumber(options.defaults.maxRetriesPerChunk, 'defaults.maxRetriesPerChunk'),
60
+ requireIdempotencyToken: parseBoolean(options.defaults.requireIdempotencyToken, 'defaults.requireIdempotencyToken'),
61
+ };
62
+ }
63
+ if (options.policy !== undefined) {
64
+ if (!isRecord(options.policy)) {
65
+ throw new BackfillConfigError('Invalid plugin option "policy". Expected object.');
66
+ }
67
+ normalized.policy = {
68
+ requireDryRunBeforeRun: parseBoolean(options.policy.requireDryRunBeforeRun, 'policy.requireDryRunBeforeRun'),
69
+ requireExplicitWindow: parseBoolean(options.policy.requireExplicitWindow, 'policy.requireExplicitWindow'),
70
+ blockOverlappingRuns: parseBoolean(options.policy.blockOverlappingRuns, 'policy.blockOverlappingRuns'),
71
+ failCheckOnRequiredPendingBackfill: parseBoolean(options.policy.failCheckOnRequiredPendingBackfill, 'policy.failCheckOnRequiredPendingBackfill'),
72
+ };
73
+ }
74
+ if (options.limits !== undefined) {
75
+ if (!isRecord(options.limits)) {
76
+ throw new BackfillConfigError('Invalid plugin option "limits". Expected object.');
77
+ }
78
+ normalized.limits = {
79
+ maxWindowHours: parsePositiveNumber(options.limits.maxWindowHours, 'limits.maxWindowHours'),
80
+ minChunkMinutes: parsePositiveNumber(options.limits.minChunkMinutes, 'limits.minChunkMinutes'),
81
+ };
82
+ }
83
+ return normalized;
84
+ }
85
+ export function normalizeBackfillOptions(options = {}) {
86
+ return {
87
+ stateDir: options.stateDir,
88
+ defaults: {
89
+ ...DEFAULT_OPTIONS.defaults,
90
+ ...(options.defaults ?? {}),
91
+ },
92
+ policy: {
93
+ ...DEFAULT_OPTIONS.policy,
94
+ ...(options.policy ?? {}),
95
+ },
96
+ limits: {
97
+ ...DEFAULT_OPTIONS.limits,
98
+ ...(options.limits ?? {}),
99
+ },
100
+ };
101
+ }
102
+ export function mergeOptions(baseOptions, runtimeOptions) {
103
+ const fromRuntime = normalizeRuntimeOptions(runtimeOptions);
104
+ return normalizeBackfillOptions({
105
+ stateDir: fromRuntime.stateDir ?? baseOptions.stateDir,
106
+ defaults: {
107
+ ...baseOptions.defaults,
108
+ ...(fromRuntime.defaults ?? {}),
109
+ },
110
+ policy: {
111
+ ...baseOptions.policy,
112
+ ...(fromRuntime.policy ?? {}),
113
+ },
114
+ limits: {
115
+ ...baseOptions.limits,
116
+ ...(fromRuntime.limits ?? {}),
117
+ },
118
+ });
119
+ }
120
+ export function validateBaseOptions(options) {
121
+ if (options.defaults.chunkHours * 60 < options.limits.minChunkMinutes) {
122
+ throw new BackfillConfigError(`defaults.chunkHours (${options.defaults.chunkHours}) must be >= limits.minChunkMinutes (${options.limits.minChunkMinutes}m).`);
123
+ }
124
+ }
125
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { BackfillDoctorReport, BackfillPlanStatus, BackfillStatusSummary, BuildBackfillPlanOutput, ExecuteBackfillRunOutput } from './types.js';
2
+ export declare function planPayload(output: BuildBackfillPlanOutput): {
3
+ ok: true;
4
+ command: 'plan';
5
+ planId: string;
6
+ target: string;
7
+ from: string;
8
+ to: string;
9
+ chunkCount: number;
10
+ chunkHours: number;
11
+ planPath: string;
12
+ existed: boolean;
13
+ };
14
+ export declare function runPayload(output: ExecuteBackfillRunOutput): {
15
+ ok: boolean;
16
+ command: 'run' | 'resume';
17
+ planId: string;
18
+ status: BackfillPlanStatus;
19
+ chunkCounts: BackfillStatusSummary['totals'];
20
+ attempts: number;
21
+ runPath: string;
22
+ eventPath: string;
23
+ lastError?: string;
24
+ };
25
+ export declare function statusPayload(summary: BackfillStatusSummary): {
26
+ ok: boolean;
27
+ command: 'status';
28
+ planId: string;
29
+ status: BackfillPlanStatus;
30
+ chunkCounts: BackfillStatusSummary['totals'];
31
+ attempts: number;
32
+ runPath: string;
33
+ eventPath: string;
34
+ updatedAt: string;
35
+ lastError?: string;
36
+ };
37
+ export declare function cancelPayload(summary: BackfillStatusSummary): {
38
+ ok: boolean;
39
+ command: 'cancel';
40
+ planId: string;
41
+ status: BackfillPlanStatus;
42
+ chunkCounts: BackfillStatusSummary['totals'];
43
+ runPath: string;
44
+ eventPath: string;
45
+ };
46
+ export declare function doctorPayload(report: BackfillDoctorReport): {
47
+ ok: boolean;
48
+ command: 'doctor';
49
+ planId: string;
50
+ status: BackfillPlanStatus;
51
+ issueCodes: string[];
52
+ recommendations: string[];
53
+ failedChunkIds: string[];
54
+ };
55
+ //# sourceMappingURL=payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,YAAY,CAAA;AAEnB,wBAAgB,WAAW,CAAC,MAAM,EAAE,uBAAuB,GAAG;IAC5D,EAAE,EAAE,IAAI,CAAA;IACR,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;CACjB,CAaA;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG;IAC5D,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,EAAE,KAAK,GAAG,QAAQ,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,kBAAkB,CAAA;IAC1B,WAAW,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAA;IAC5C,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAYA;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG;IAC7D,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,EAAE,QAAQ,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,kBAAkB,CAAA;IAC1B,WAAW,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAA;IAC5C,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAaA;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG;IAC7D,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,EAAE,QAAQ,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,kBAAkB,CAAA;IAC1B,WAAW,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAA;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAUA;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,oBAAoB,GAAG;IAC3D,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,EAAE,QAAQ,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,kBAAkB,CAAA;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB,CAUA"}
@@ -0,0 +1,64 @@
1
+ export function planPayload(output) {
2
+ return {
3
+ ok: true,
4
+ command: 'plan',
5
+ planId: output.plan.planId,
6
+ target: output.plan.target,
7
+ from: output.plan.from,
8
+ to: output.plan.to,
9
+ chunkCount: output.plan.chunks.length,
10
+ chunkHours: output.plan.options.chunkHours,
11
+ planPath: output.planPath,
12
+ existed: output.existed,
13
+ };
14
+ }
15
+ export function runPayload(output) {
16
+ return {
17
+ ok: output.status.status === 'completed',
18
+ command: 'run',
19
+ planId: output.run.planId,
20
+ status: output.status.status,
21
+ chunkCounts: output.status.totals,
22
+ attempts: output.status.attempts,
23
+ runPath: output.runPath,
24
+ eventPath: output.eventPath,
25
+ lastError: output.status.lastError,
26
+ };
27
+ }
28
+ export function statusPayload(summary) {
29
+ return {
30
+ ok: summary.status !== 'failed',
31
+ command: 'status',
32
+ planId: summary.planId,
33
+ status: summary.status,
34
+ chunkCounts: summary.totals,
35
+ attempts: summary.attempts,
36
+ runPath: summary.runPath,
37
+ eventPath: summary.eventPath,
38
+ updatedAt: summary.updatedAt,
39
+ lastError: summary.lastError,
40
+ };
41
+ }
42
+ export function cancelPayload(summary) {
43
+ return {
44
+ ok: summary.status === 'cancelled',
45
+ command: 'cancel',
46
+ planId: summary.planId,
47
+ status: summary.status,
48
+ chunkCounts: summary.totals,
49
+ runPath: summary.runPath,
50
+ eventPath: summary.eventPath,
51
+ };
52
+ }
53
+ export function doctorPayload(report) {
54
+ return {
55
+ ok: report.issueCodes.length === 0,
56
+ command: 'doctor',
57
+ planId: report.planId,
58
+ status: report.status,
59
+ issueCodes: report.issueCodes,
60
+ recommendations: report.recommendations,
61
+ failedChunkIds: report.failedChunkIds,
62
+ };
63
+ }
64
+ //# sourceMappingURL=payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,WAAW,CAAC,MAA+B;IAYzD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;QAC1B,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;QAC1B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;QACtB,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;QAClB,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM;QACrC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU;QAC1C,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAgC;IAWzD,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,WAAW;QACxC,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;QAC5B,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;QACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ;QAChC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS;KACnC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAA8B;IAY1D,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,MAAM,KAAK,QAAQ;QAC/B,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAA8B;IAS1D,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,MAAM,KAAK,WAAW;QAClC,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAA4B;IASxD,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;QAClC,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAA;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ResolvedChxConfig } from '@chkit/core';
2
+ import type { BuildBackfillPlanOutput, NormalizedBackfillPluginOptions } from './types.js';
3
+ export declare function buildBackfillPlan(input: {
4
+ target: string;
5
+ from: string;
6
+ to: string;
7
+ configPath: string;
8
+ config: Pick<ResolvedChxConfig, 'metaDir'>;
9
+ options: NormalizedBackfillPluginOptions;
10
+ chunkHours?: number;
11
+ forceLargeWindow?: boolean;
12
+ }): Promise<BuildBackfillPlanOutput>;
13
+ //# sourceMappingURL=planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAYpD,OAAO,KAAK,EAGV,uBAAuB,EACvB,+BAA+B,EAChC,MAAM,YAAY,CAAA;AAsFnB,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;IAC1C,OAAO,EAAE,+BAA+B,CAAA;IACxC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAiEnC"}
@@ -0,0 +1,113 @@
1
+ import { BackfillConfigError } from './errors.js';
2
+ import { backfillPaths, computeBackfillStateDir, hashId, planIdentity, readExistingPlan, stableSerialize, writeJson, } from './state.js';
3
+ function ensureHoursWithinLimits(input) {
4
+ const fromMillis = new Date(input.from).getTime();
5
+ const toMillis = new Date(input.to).getTime();
6
+ if (toMillis <= fromMillis) {
7
+ throw new BackfillConfigError('Invalid backfill window. Expected --to to be after --from.');
8
+ }
9
+ const durationHours = (toMillis - fromMillis) / (1000 * 60 * 60);
10
+ if (durationHours > input.limits.maxWindowHours && !input.forceLargeWindow) {
11
+ throw new BackfillConfigError(`Requested window (${durationHours.toFixed(2)} hours) exceeds limits.maxWindowHours=${input.limits.maxWindowHours}. Retry with --force-large-window to acknowledge risk.`);
12
+ }
13
+ }
14
+ function buildChunkSqlTemplate(chunk) {
15
+ return [
16
+ `/* chx backfill plan=${chunk.planId} chunk=${chunk.chunkId} token=${chunk.token} */`,
17
+ `INSERT INTO ${chunk.target}`,
18
+ `SELECT *`,
19
+ `FROM ${chunk.target}`,
20
+ `WHERE event_time >= toDateTime('${chunk.from}')`,
21
+ ` AND event_time < toDateTime('${chunk.to}');`,
22
+ ].join('\n');
23
+ }
24
+ function buildChunks(input) {
25
+ const fromMillis = new Date(input.from).getTime();
26
+ const toMillis = new Date(input.to).getTime();
27
+ const chunkMillis = input.chunkHours * 60 * 60 * 1000;
28
+ const chunks = [];
29
+ let current = fromMillis;
30
+ while (current < toMillis) {
31
+ const next = Math.min(current + chunkMillis, toMillis);
32
+ const chunkFrom = new Date(current).toISOString();
33
+ const chunkTo = new Date(next).toISOString();
34
+ const idSeed = `${input.planId}:${chunkFrom}:${chunkTo}`;
35
+ const chunkId = hashId(`chunk:${idSeed}`).slice(0, 16);
36
+ const token = input.requireIdempotencyToken ? hashId(`token:${idSeed}`) : '';
37
+ chunks.push({
38
+ id: chunkId,
39
+ from: chunkFrom,
40
+ to: chunkTo,
41
+ status: 'pending',
42
+ attempts: 0,
43
+ idempotencyToken: token,
44
+ sqlTemplate: buildChunkSqlTemplate({
45
+ planId: input.planId,
46
+ chunkId,
47
+ token,
48
+ target: input.target,
49
+ from: chunkFrom,
50
+ to: chunkTo,
51
+ }),
52
+ });
53
+ current = next;
54
+ }
55
+ return chunks;
56
+ }
57
+ export async function buildBackfillPlan(input) {
58
+ const chunkHours = input.chunkHours ?? input.options.defaults.chunkHours;
59
+ if (chunkHours * 60 < input.options.limits.minChunkMinutes) {
60
+ throw new BackfillConfigError(`Chunk size ${chunkHours}h is below limits.minChunkMinutes=${input.options.limits.minChunkMinutes}.`);
61
+ }
62
+ ensureHoursWithinLimits({
63
+ from: input.from,
64
+ to: input.to,
65
+ limits: input.options.limits,
66
+ forceLargeWindow: input.forceLargeWindow ?? false,
67
+ });
68
+ const planId = hashId(planIdentity(input.target, input.from, input.to, chunkHours)).slice(0, 16);
69
+ const stateDir = computeBackfillStateDir(input.config, input.configPath, input.options);
70
+ const paths = backfillPaths(stateDir, planId);
71
+ const plan = {
72
+ planId,
73
+ target: input.target,
74
+ createdAt: '1970-01-01T00:00:00.000Z',
75
+ status: 'planned',
76
+ from: input.from,
77
+ to: input.to,
78
+ chunks: buildChunks({
79
+ planId,
80
+ target: input.target,
81
+ from: input.from,
82
+ to: input.to,
83
+ chunkHours,
84
+ requireIdempotencyToken: input.options.defaults.requireIdempotencyToken,
85
+ }),
86
+ options: {
87
+ chunkHours,
88
+ maxParallelChunks: input.options.defaults.maxParallelChunks,
89
+ maxRetriesPerChunk: input.options.defaults.maxRetriesPerChunk,
90
+ requireIdempotencyToken: input.options.defaults.requireIdempotencyToken,
91
+ },
92
+ policy: input.options.policy,
93
+ limits: input.options.limits,
94
+ };
95
+ const existing = await readExistingPlan(paths.planPath);
96
+ if (existing) {
97
+ if (stableSerialize(existing) !== stableSerialize(plan)) {
98
+ throw new BackfillConfigError(`Backfill plan already exists at ${paths.planPath} but differs from current planning output. Remove it if you intentionally changed planning parameters.`);
99
+ }
100
+ return {
101
+ plan: existing,
102
+ planPath: paths.planPath,
103
+ existed: true,
104
+ };
105
+ }
106
+ await writeJson(paths.planPath, plan);
107
+ return {
108
+ plan,
109
+ planPath: paths.planPath,
110
+ existed: false,
111
+ };
112
+ }
113
+ //# sourceMappingURL=planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.js","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"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"}