@zukhruf/sqlite-queue 0.0.0-stage → 0.3.41
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/LICENSE +21 -0
- package/README.md +151 -2
- package/dist/activity.d.ts +10 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +93 -0
- package/dist/activity.js.map +1 -0
- package/dist/attorney.d.ts +35 -0
- package/dist/attorney.d.ts.map +1 -0
- package/dist/attorney.js +367 -0
- package/dist/attorney.js.map +1 -0
- package/dist/claim-timer.d.ts +8 -0
- package/dist/claim-timer.d.ts.map +1 -0
- package/dist/claim-timer.js +80 -0
- package/dist/claim-timer.js.map +1 -0
- package/dist/completion-data.d.ts +6 -0
- package/dist/completion-data.d.ts.map +1 -0
- package/dist/completion-data.js +36 -0
- package/dist/completion-data.js.map +1 -0
- package/dist/database-error.d.ts +6 -0
- package/dist/database-error.d.ts.map +1 -0
- package/dist/database-error.js +12 -0
- package/dist/database-error.js.map +1 -0
- package/dist/database.d.ts +7 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +28 -0
- package/dist/database.js.map +1 -0
- package/dist/in-flight.d.ts +7 -0
- package/dist/in-flight.d.ts.map +1 -0
- package/dist/in-flight.js +24 -0
- package/dist/in-flight.js.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1069 -0
- package/dist/index.js.map +1 -0
- package/dist/job-fetcher.d.ts +16 -0
- package/dist/job-fetcher.d.ts.map +1 -0
- package/dist/job-fetcher.js +227 -0
- package/dist/job-fetcher.js.map +1 -0
- package/dist/job-queue.d.ts +27 -0
- package/dist/job-queue.d.ts.map +1 -0
- package/dist/job-queue.js +2 -0
- package/dist/job-queue.js.map +1 -0
- package/dist/job-rows.d.ts +49 -0
- package/dist/job-rows.d.ts.map +1 -0
- package/dist/job-rows.js +155 -0
- package/dist/job-rows.js.map +1 -0
- package/dist/job-settler.d.ts +24 -0
- package/dist/job-settler.d.ts.map +1 -0
- package/dist/job-settler.js +240 -0
- package/dist/job-settler.js.map +1 -0
- package/dist/jsonb.d.ts +7 -0
- package/dist/jsonb.d.ts.map +1 -0
- package/dist/jsonb.js +85 -0
- package/dist/jsonb.js.map +1 -0
- package/dist/local-groups.d.ts +16 -0
- package/dist/local-groups.d.ts.map +1 -0
- package/dist/local-groups.js +113 -0
- package/dist/local-groups.js.map +1 -0
- package/dist/naive-timestamp.d.ts +6 -0
- package/dist/naive-timestamp.d.ts.map +1 -0
- package/dist/naive-timestamp.js +21 -0
- package/dist/naive-timestamp.js.map +1 -0
- package/dist/queue-cache.d.ts +9 -0
- package/dist/queue-cache.d.ts.map +1 -0
- package/dist/queue-cache.js +27 -0
- package/dist/queue-cache.js.map +1 -0
- package/dist/queue-rows.d.ts +25 -0
- package/dist/queue-rows.d.ts.map +1 -0
- package/dist/queue-rows.js +44 -0
- package/dist/queue-rows.js.map +1 -0
- package/dist/recurrence.d.ts +11 -0
- package/dist/recurrence.d.ts.map +1 -0
- package/dist/recurrence.js +226 -0
- package/dist/recurrence.js.map +1 -0
- package/dist/rows.d.ts +10 -0
- package/dist/rows.d.ts.map +1 -0
- package/dist/rows.js +46 -0
- package/dist/rows.js.map +1 -0
- package/dist/schema.d.ts +3 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +139 -0
- package/dist/schema.js.map +1 -0
- package/dist/sql-values.d.ts +9 -0
- package/dist/sql-values.d.ts.map +1 -0
- package/dist/sql-values.js +26 -0
- package/dist/sql-values.js.map +1 -0
- package/dist/start-after.d.ts +10 -0
- package/dist/start-after.d.ts.map +1 -0
- package/dist/start-after.js +125 -0
- package/dist/start-after.js.map +1 -0
- package/dist/supervisor.d.ts +16 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +288 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/throttle.d.ts +6 -0
- package/dist/throttle.d.ts.map +1 -0
- package/dist/throttle.js +35 -0
- package/dist/throttle.js.map +1 -0
- package/dist/timekeeper.d.ts +36 -0
- package/dist/timekeeper.d.ts.map +1 -0
- package/dist/timekeeper.js +305 -0
- package/dist/timekeeper.js.map +1 -0
- package/dist/timers.d.ts +9 -0
- package/dist/timers.d.ts.map +1 -0
- package/dist/timers.js +50 -0
- package/dist/timers.js.map +1 -0
- package/dist/uuid.d.ts +7 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +36 -0
- package/dist/uuid.js.map +1 -0
- package/dist/worker.d.ts +35 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +147 -0
- package/dist/worker.js.map +1 -0
- package/package.json +53 -4
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type QueuePolicy } from 'pg-boss';
|
|
2
|
+
import type { SqliteRow } from './rows.ts';
|
|
3
|
+
export type QueueRow = {
|
|
4
|
+
name: string;
|
|
5
|
+
policy: QueuePolicy;
|
|
6
|
+
retry_limit: number;
|
|
7
|
+
retry_delay_seconds: number;
|
|
8
|
+
retry_backoff: number;
|
|
9
|
+
retry_delay_max_seconds: number | null;
|
|
10
|
+
expire_seconds: number;
|
|
11
|
+
retention_seconds: number;
|
|
12
|
+
deletion_seconds: number;
|
|
13
|
+
heartbeat_seconds: number | null;
|
|
14
|
+
dead_letter: string | null;
|
|
15
|
+
warning_queue_size: number;
|
|
16
|
+
notify: boolean;
|
|
17
|
+
ready_count: number;
|
|
18
|
+
singletons_active: (string | null)[] | null;
|
|
19
|
+
};
|
|
20
|
+
export declare class QueueRows {
|
|
21
|
+
#private;
|
|
22
|
+
static readPolicy(row: SqliteRow): QueueRow['policy'];
|
|
23
|
+
static decode(value: unknown): QueueRow;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=queue-rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-rows.d.ts","sourceRoot":"","sources":["../src/queue-rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,SAAS,CAAC;AAGrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;CAC7C,CAAC;AAEF,qBAAa,SAAS;;IACpB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC;IASrD,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ;CA0CxC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { policies } from 'pg-boss';
|
|
2
|
+
import { Row } from "./rows.js";
|
|
3
|
+
export class QueueRows {
|
|
4
|
+
static readPolicy(row) {
|
|
5
|
+
const policy = Row.readString(row, 'policy');
|
|
6
|
+
if (Object.values(policies).some((known) => known === policy)) {
|
|
7
|
+
return policy;
|
|
8
|
+
}
|
|
9
|
+
throw new Error(`Unsupported SQLite queue policy: ${policy}`);
|
|
10
|
+
}
|
|
11
|
+
static decode(value) {
|
|
12
|
+
const row = Row.parse(value, 'queue');
|
|
13
|
+
return {
|
|
14
|
+
name: Row.readString(row, 'name'),
|
|
15
|
+
policy: QueueRows.readPolicy(row),
|
|
16
|
+
retry_limit: Row.readNumber(row, 'retry_limit'),
|
|
17
|
+
retry_delay_seconds: Row.readNumber(row, 'retry_delay_seconds'),
|
|
18
|
+
retry_backoff: Row.readNumber(row, 'retry_backoff'),
|
|
19
|
+
retry_delay_max_seconds: Row.readNullableNumber(row, 'retry_delay_max_seconds'),
|
|
20
|
+
expire_seconds: Row.readNumber(row, 'expire_seconds'),
|
|
21
|
+
retention_seconds: Row.readNumber(row, 'retention_seconds'),
|
|
22
|
+
deletion_seconds: Row.readNumber(row, 'deletion_seconds'),
|
|
23
|
+
heartbeat_seconds: Row.readNullableNumber(row, 'heartbeat_seconds'),
|
|
24
|
+
dead_letter: Row.readNullableString(row, 'dead_letter'),
|
|
25
|
+
warning_queue_size: Row.readNumber(row, 'warning_queue_size'),
|
|
26
|
+
notify: Row.readNumber(row, 'notify') === 1,
|
|
27
|
+
ready_count: Row.readNumber(row, 'ready_count'),
|
|
28
|
+
singletons_active: QueueRows.#readKeys(row, 'singletons_active'),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
static #readKeys(row, column) {
|
|
32
|
+
const text = Row.readNullableString(row, column);
|
|
33
|
+
if (text === null) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const keys = JSON.parse(text);
|
|
37
|
+
if (Array.isArray(keys) &&
|
|
38
|
+
keys.every((key) => key === null || typeof key === 'string')) {
|
|
39
|
+
return keys;
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`Expected a JSON array of keys in SQLite column: ${column}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=queue-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-rows.js","sourceRoot":"","sources":["../src/queue-rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,QAAQ,EAAE,MAAM,SAAS,CAAC;AAErD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAqBhC,MAAM,OAAO,SAAS;IACpB,MAAM,CAAC,UAAU,CAAC,GAAc;QAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,EAAE,CAAC;YAC9D,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,KAAc;QAC1B,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;YACjC,MAAM,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;YACjC,WAAW,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC;YAC/C,mBAAmB,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,qBAAqB,CAAC;YAC/D,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,eAAe,CAAC;YACnD,uBAAuB,EAAE,GAAG,CAAC,kBAAkB,CAC7C,GAAG,EACH,yBAAyB,CAC1B;YACD,cAAc,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,gBAAgB,CAAC;YACrD,iBAAiB,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,mBAAmB,CAAC;YAC3D,gBAAgB,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,kBAAkB,CAAC;YACzD,iBAAiB,EAAE,GAAG,CAAC,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,CAAC;YACnE,WAAW,EAAE,GAAG,CAAC,kBAAkB,CAAC,GAAG,EAAE,aAAa,CAAC;YACvD,kBAAkB,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,oBAAoB,CAAC;YAC7D,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC;YAC3C,WAAW,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC;YAC/C,iBAAiB,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,mBAAmB,CAAC;SACjE,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,GAAc,EAAE,MAAc;QAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IACE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YACnB,IAAI,CAAC,KAAK,CACR,CAAC,GAAG,EAAwB,EAAE,CAAC,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,CACvE,EACD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,KAAK,CACb,mDAAmD,MAAM,EAAE,CAC5D,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class Recurrence {
|
|
2
|
+
#private;
|
|
3
|
+
static isRrule(expression: string): boolean;
|
|
4
|
+
static assertRecurrence(expression: string, tz: string): void;
|
|
5
|
+
static assertTimezone(tz: unknown): void;
|
|
6
|
+
static assertRruleSends(expression: string, tz: string, from: Date): void;
|
|
7
|
+
static assertMissedPolicy(missed: unknown): void;
|
|
8
|
+
static occurrencesInWindow(expression: string, after: Date, until: Date, tz: string): Date[];
|
|
9
|
+
static latestOccurrenceBefore(expression: string, after: Date, until: Date, tz: string): Date | null;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=recurrence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurrence.d.ts","sourceRoot":"","sources":["../src/recurrence.ts"],"names":[],"mappings":"AAUA,qBAAa,UAAU;;IA0CrB,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAM3C,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAU7D,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI;IAiBxC,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI;IAQzE,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAoIhD,MAAM,CAAC,mBAAmB,CACxB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACX,EAAE,EAAE,MAAM,GACT,IAAI,EAAE;IAUT,MAAM,CAAC,sBAAsB,CAC3B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACX,EAAE,EAAE,MAAM,GACT,IAAI,GAAG,IAAI;CAkCf"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { CronExpressionParser } from 'cron-parser';
|
|
3
|
+
import { scheduleMissedPolicies } from 'pg-boss';
|
|
4
|
+
import { RRuleTemporal } from 'rrule-temporal';
|
|
5
|
+
// pg-boss's checks on a schedule's recurrence (node_modules/pg-boss/dist/
|
|
6
|
+
// rrule.js, timezone.js and timekeeper.js, 12.35.1). None of them is
|
|
7
|
+
// exported, so each is ported by citation and proven equal by the parity
|
|
8
|
+
// suite.
|
|
9
|
+
export class Recurrence {
|
|
10
|
+
// rrule.js:17
|
|
11
|
+
static #epochDtstart = '19700101T000000';
|
|
12
|
+
// rrule.js:23
|
|
13
|
+
static #properties = new Set([
|
|
14
|
+
'DTSTART',
|
|
15
|
+
'RRULE',
|
|
16
|
+
'RDATE',
|
|
17
|
+
'EXDATE',
|
|
18
|
+
]);
|
|
19
|
+
// rrule.js:33-50
|
|
20
|
+
static #partOptions = new Map([
|
|
21
|
+
['FREQ', 'freq'],
|
|
22
|
+
['UNTIL', 'until'],
|
|
23
|
+
['COUNT', 'count'],
|
|
24
|
+
['INTERVAL', 'interval'],
|
|
25
|
+
['BYSECOND', 'bySecond'],
|
|
26
|
+
['BYMINUTE', 'byMinute'],
|
|
27
|
+
['BYHOUR', 'byHour'],
|
|
28
|
+
['BYDAY', 'byDay'],
|
|
29
|
+
['BYMONTHDAY', 'byMonthDay'],
|
|
30
|
+
['BYYEARDAY', 'byYearDay'],
|
|
31
|
+
['BYWEEKNO', 'byWeekNo'],
|
|
32
|
+
['BYMONTH', 'byMonth'],
|
|
33
|
+
['BYSETPOS', 'bySetPos'],
|
|
34
|
+
['WKST', 'wkst'],
|
|
35
|
+
['RSCALE', 'rscale'],
|
|
36
|
+
['SKIP', 'skip'],
|
|
37
|
+
]);
|
|
38
|
+
// rrule.js:52
|
|
39
|
+
static #property = /^([a-z][a-z0-9-]*)[;:]/i;
|
|
40
|
+
// rrule.js:63
|
|
41
|
+
static #rruleShape = /^[ \t]*[a-z][a-z0-9-]*[;:]|(?:^|[\s;])FREQ=/im;
|
|
42
|
+
// rrule.js:290-291
|
|
43
|
+
static #stepSeconds = 60 * 60;
|
|
44
|
+
static #stepGrowth = 4;
|
|
45
|
+
// timekeeper.js:48
|
|
46
|
+
static #missedPolicies = Object.values(scheduleMissedPolicies);
|
|
47
|
+
// rrule.js:65-67
|
|
48
|
+
static isRrule(expression) {
|
|
49
|
+
return Recurrence.#rruleShape.test(expression);
|
|
50
|
+
}
|
|
51
|
+
// timekeeper.js:185-194. parseRecurrence's walk (176-180) is for
|
|
52
|
+
// previewSchedule, so only its two checks are kept.
|
|
53
|
+
static assertRecurrence(expression, tz) {
|
|
54
|
+
if (Recurrence.isRrule(expression)) {
|
|
55
|
+
Recurrence.#assertRrule(expression, tz);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
CronExpressionParser.parse(expression, { tz: 'UTC', strict: false });
|
|
59
|
+
Recurrence.assertTimezone(tz);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// timezone.js:18-33
|
|
63
|
+
static assertTimezone(tz) {
|
|
64
|
+
const unusable = `Unknown or unsupported time zone: ${typeof tz === 'string' ? `"${tz}"` : String(tz)}`;
|
|
65
|
+
if (typeof tz !== 'string') {
|
|
66
|
+
throw new Error(unusable);
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
CronExpressionParser.parse('* * * * *', {
|
|
70
|
+
tz,
|
|
71
|
+
strict: false,
|
|
72
|
+
currentDate: new Date(),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
throw new Error(unusable);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// rrule.js:382-384
|
|
80
|
+
static assertRruleSends(expression, tz, from) {
|
|
81
|
+
assert(Recurrence.#parseRule(expression, tz).next(from) !== null, 'rrule expression has no occurrence left, so the schedule would never send a job');
|
|
82
|
+
}
|
|
83
|
+
// timekeeper.js:156-163
|
|
84
|
+
static assertMissedPolicy(missed) {
|
|
85
|
+
assert(missed === undefined ||
|
|
86
|
+
missed === null ||
|
|
87
|
+
Recurrence.#missedPolicies.includes(missed), `missed must be one of: ${Recurrence.#missedPolicies.join(', ')}`);
|
|
88
|
+
}
|
|
89
|
+
// rrule.js:359-370
|
|
90
|
+
static #assertRrule(expression, tz) {
|
|
91
|
+
const { ics, rule } = Recurrence.#toIcs(expression);
|
|
92
|
+
Recurrence.#assertValues(rule, Recurrence.#buildRule(ics, 'UTC'));
|
|
93
|
+
Recurrence.assertTimezone(tz);
|
|
94
|
+
}
|
|
95
|
+
// rrule.js:76-131
|
|
96
|
+
static #toIcs(expression) {
|
|
97
|
+
const lines = [];
|
|
98
|
+
const dates = [];
|
|
99
|
+
let dtstart = null;
|
|
100
|
+
let rule = null;
|
|
101
|
+
for (const line of expression.replace(/\r?\n[ \t]/g, '').split(/\r?\n/)) {
|
|
102
|
+
const text = line.trim();
|
|
103
|
+
if (text.length === 0) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const property = Recurrence.#property.exec(text)?.[1]?.toUpperCase();
|
|
107
|
+
const name = property || 'RRULE';
|
|
108
|
+
const value = property ? text.slice(text.indexOf(':') + 1) : text;
|
|
109
|
+
assert(name !== 'BEGIN' && name !== 'END', 'rrule expression should be the DTSTART, RRULE, RDATE and EXDATE lines of a calendar entry, without the BEGIN and END lines around them');
|
|
110
|
+
assert(Recurrence.#properties.has(name), `Unsupported property "${name}" in rrule expression. Supported properties: ${[...Recurrence.#properties].join(', ')}`);
|
|
111
|
+
if (name === 'DTSTART') {
|
|
112
|
+
assert(dtstart === null, 'rrule expression has more than one DTSTART');
|
|
113
|
+
dtstart = value;
|
|
114
|
+
}
|
|
115
|
+
if (name === 'RRULE') {
|
|
116
|
+
assert(rule === null, 'rrule expression has more than one RRULE');
|
|
117
|
+
rule = value;
|
|
118
|
+
Recurrence.#assertParts(value);
|
|
119
|
+
}
|
|
120
|
+
if (name === 'RDATE' || name === 'EXDATE') {
|
|
121
|
+
dates.push([name, value]);
|
|
122
|
+
}
|
|
123
|
+
lines.push(property ? text : `RRULE:${text}`);
|
|
124
|
+
}
|
|
125
|
+
assert(rule !== null, 'rrule expression has no RRULE to recur on');
|
|
126
|
+
if (dtstart === null) {
|
|
127
|
+
assert(!/(^|;)COUNT=/i.test(rule), 'rrule expression uses COUNT, which counts occurrences from DTSTART, so it needs a DTSTART of its own');
|
|
128
|
+
lines.unshift(`DTSTART:${Recurrence.#epochDtstart}`);
|
|
129
|
+
}
|
|
130
|
+
Recurrence.#assertDates(dates, dtstart ?? Recurrence.#epochDtstart);
|
|
131
|
+
return { ics: lines.join('\n'), rule };
|
|
132
|
+
}
|
|
133
|
+
// rrule.js:134-155
|
|
134
|
+
static #assertParts(rule) {
|
|
135
|
+
const named = new Set();
|
|
136
|
+
for (const part of rule.split(';')) {
|
|
137
|
+
if (part.length === 0) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const [name = '', value = ''] = part.toUpperCase().split('=');
|
|
141
|
+
assert(value.length > 0, `rrule part "${part}" has no value`);
|
|
142
|
+
assert(Recurrence.#partOptions.has(name) || name.startsWith('X-'), `Unsupported part "${part}" in rrule expression`);
|
|
143
|
+
assert(!named.has(name), `rrule expression has more than one ${name} part`);
|
|
144
|
+
named.add(name);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// rrule.js:162-175
|
|
148
|
+
static #assertDates(dates, dtstart) {
|
|
149
|
+
const dtstartIsDate = !dtstart.includes('T');
|
|
150
|
+
for (const [name, value] of dates) {
|
|
151
|
+
for (const date of value.split(',')) {
|
|
152
|
+
const expected = dtstartIsDate
|
|
153
|
+
? `a date such as ${date.slice(0, 8)}`
|
|
154
|
+
: `a date time such as ${date}T090000`;
|
|
155
|
+
assert(date.includes('T') !== dtstartIsDate, `rrule ${name} "${date}" must have the same value type as DTSTART: ${expected}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// rrule.js:184-203
|
|
160
|
+
static #assertValues(rule, built) {
|
|
161
|
+
const options = new Map(Object.entries({ ...built.options() }));
|
|
162
|
+
for (const part of rule.split(';')) {
|
|
163
|
+
const [name = '', value = ''] = part.split('=');
|
|
164
|
+
const option = Recurrence.#partOptions.get(name.toUpperCase());
|
|
165
|
+
if (option === undefined) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const parsed = options.get(option);
|
|
169
|
+
const message = `Unsupported value in rrule part "${part}"`;
|
|
170
|
+
assert(parsed !== undefined, message);
|
|
171
|
+
if (Array.isArray(parsed)) {
|
|
172
|
+
assert(parsed.length === new Set(value.toUpperCase().split(',')).size, message);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// rrule.js:205-211
|
|
177
|
+
static #buildRule(ics, tz) {
|
|
178
|
+
return new RRuleTemporal({ rruleString: ics, tzid: tz, strict: true });
|
|
179
|
+
}
|
|
180
|
+
// rrule.js:268-274, 281: every occurrence in (after, until], in order. between()
|
|
181
|
+
// excludes both ends, so the upper one is nudged past.
|
|
182
|
+
static occurrencesInWindow(expression, after, until, tz) {
|
|
183
|
+
return Recurrence.#parseRule(expression, tz)
|
|
184
|
+
.between(after, new Date(until.getTime() + 1))
|
|
185
|
+
.map((occurrence) => new Date(occurrence.epochMilliseconds));
|
|
186
|
+
}
|
|
187
|
+
// rrule.js:323-356: the latest occurrence in (after, until], read in steps
|
|
188
|
+
// that widen backwards from `until`. A step rrule-temporal refuses as too
|
|
189
|
+
// dense is halved and read again, and its width caps every later step; one
|
|
190
|
+
// refused at the floor is the expression's own fault, so it throws.
|
|
191
|
+
static latestOccurrenceBefore(expression, after, until, tz) {
|
|
192
|
+
const rule = Recurrence.#parseRule(expression, tz);
|
|
193
|
+
const floor = Recurrence.#stepSeconds * 1000;
|
|
194
|
+
const start = after.getTime();
|
|
195
|
+
let upper = until.getTime();
|
|
196
|
+
let width = floor;
|
|
197
|
+
let ceiling = Number.POSITIVE_INFINITY;
|
|
198
|
+
while (upper > start) {
|
|
199
|
+
const lower = Math.max(start, upper - width);
|
|
200
|
+
let step;
|
|
201
|
+
try {
|
|
202
|
+
step = rule.between(new Date(lower), new Date(upper + 1));
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
if (upper - lower <= floor) {
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
208
|
+
ceiling = Math.max(floor, Math.floor((upper - lower) / 2));
|
|
209
|
+
width = ceiling;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const latest = step.at(-1);
|
|
213
|
+
if (latest !== undefined) {
|
|
214
|
+
return new Date(latest.epochMilliseconds);
|
|
215
|
+
}
|
|
216
|
+
upper = lower;
|
|
217
|
+
width = Math.min(width * Recurrence.#stepGrowth, ceiling);
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
// rrule.js:221-223
|
|
222
|
+
static #parseRule(expression, tz) {
|
|
223
|
+
return Recurrence.#buildRule(Recurrence.#toIcs(expression).ics, tz);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=recurrence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurrence.js","sourceRoot":"","sources":["../src/recurrence.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,0EAA0E;AAC1E,qEAAqE;AACrE,yEAAyE;AACzE,SAAS;AACT,MAAM,OAAO,UAAU;IACrB,cAAc;IACd,MAAM,CAAU,aAAa,GAAG,iBAAiB,CAAC;IAClD,cAAc;IACd,MAAM,CAAU,WAAW,GAAG,IAAI,GAAG,CAAC;QACpC,SAAS;QACT,OAAO;QACP,OAAO;QACP,QAAQ;KACT,CAAC,CAAC;IACH,iBAAiB;IACjB,MAAM,CAAU,YAAY,GAAG,IAAI,GAAG,CAAC;QACrC,CAAC,MAAM,EAAE,MAAM,CAAC;QAChB,CAAC,OAAO,EAAE,OAAO,CAAC;QAClB,CAAC,OAAO,EAAE,OAAO,CAAC;QAClB,CAAC,UAAU,EAAE,UAAU,CAAC;QACxB,CAAC,UAAU,EAAE,UAAU,CAAC;QACxB,CAAC,UAAU,EAAE,UAAU,CAAC;QACxB,CAAC,QAAQ,EAAE,QAAQ,CAAC;QACpB,CAAC,OAAO,EAAE,OAAO,CAAC;QAClB,CAAC,YAAY,EAAE,YAAY,CAAC;QAC5B,CAAC,WAAW,EAAE,WAAW,CAAC;QAC1B,CAAC,UAAU,EAAE,UAAU,CAAC;QACxB,CAAC,SAAS,EAAE,SAAS,CAAC;QACtB,CAAC,UAAU,EAAE,UAAU,CAAC;QACxB,CAAC,MAAM,EAAE,MAAM,CAAC;QAChB,CAAC,QAAQ,EAAE,QAAQ,CAAC;QACpB,CAAC,MAAM,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,cAAc;IACd,MAAM,CAAU,SAAS,GAAG,yBAAyB,CAAC;IACtD,cAAc;IACd,MAAM,CAAU,WAAW,GAAG,+CAA+C,CAAC;IAC9E,mBAAmB;IACnB,MAAM,CAAU,YAAY,GAAG,EAAE,GAAG,EAAE,CAAC;IACvC,MAAM,CAAU,WAAW,GAAG,CAAC,CAAC;IAChC,mBAAmB;IACnB,MAAM,CAAU,eAAe,GAAuB,MAAM,CAAC,MAAM,CACjE,sBAAsB,CACvB,CAAC;IAEF,iBAAiB;IACjB,MAAM,CAAC,OAAO,CAAC,UAAkB;QAC/B,OAAO,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC;IAED,iEAAiE;IACjE,oDAAoD;IACpD,MAAM,CAAC,gBAAgB,CAAC,UAAkB,EAAE,EAAU;QACpD,IAAI,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,UAAU,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,oBAAoB,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACrE,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,CAAC,cAAc,CAAC,EAAW;QAC/B,MAAM,QAAQ,GAAG,qCAAqC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QACxG,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC;YACH,oBAAoB,CAAC,KAAK,CAAC,WAAW,EAAE;gBACtC,EAAE;gBACF,MAAM,EAAE,KAAK;gBACb,WAAW,EAAE,IAAI,IAAI,EAAE;aACxB,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,gBAAgB,CAAC,UAAkB,EAAE,EAAU,EAAE,IAAU;QAChE,MAAM,CACJ,UAAU,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EACzD,iFAAiF,CAClF,CAAC;IACJ,CAAC;IAED,wBAAwB;IACxB,MAAM,CAAC,kBAAkB,CAAC,MAAe;QACvC,MAAM,CACJ,MAAM,KAAK,SAAS;YAClB,MAAM,KAAK,IAAI;YACf,UAAU,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC7C,0BAA0B,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClE,CAAC;IACJ,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,YAAY,CAAC,UAAkB,EAAE,EAAU;QAChD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpD,UAAU,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAClE,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,kBAAkB;IAClB,MAAM,CAAC,MAAM,CAAC,UAAkB;QAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,KAAK,GAA4B,EAAE,CAAC;QAC1C,IAAI,OAAO,GAAkB,IAAI,CAAC;QAClC,IAAI,IAAI,GAAkB,IAAI,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACxE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,SAAS;YACX,CAAC;YACD,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;YACrE,MAAM,IAAI,GAAG,QAAQ,IAAI,OAAO,CAAC;YACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAClE,MAAM,CACJ,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK,EAClC,wIAAwI,CACzI,CAAC;YACF,MAAM,CACJ,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAChC,yBAAyB,IAAI,gDAAgD,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtH,CAAC;YACF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,4CAA4C,CAAC,CAAC;gBACvE,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;YACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,0CAA0C,CAAC,CAAC;gBAClE,IAAI,GAAG,KAAK,CAAC;gBACb,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACjC,CAAC;YACD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1C,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YAC5B,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,2CAA2C,CAAC,CAAC;QACnE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,CACJ,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAC1B,sGAAsG,CACvG,CAAC;YACF,KAAK,CAAC,OAAO,CAAC,WAAW,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,UAAU,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC;QACpE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,YAAY,CAAC,IAAY;QAC9B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,SAAS;YACX,CAAC;YACD,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9D,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,eAAe,IAAI,gBAAgB,CAAC,CAAC;YAC9D,MAAM,CACJ,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAC1D,qBAAqB,IAAI,uBAAuB,CACjD,CAAC;YACF,MAAM,CACJ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAChB,sCAAsC,IAAI,OAAO,CAClD,CAAC;YACF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,YAAY,CACjB,KAAsC,EACtC,OAAe;QAEf,MAAM,aAAa,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpC,MAAM,QAAQ,GAAG,aAAa;oBAC5B,CAAC,CAAC,kBAAkB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;oBACtC,CAAC,CAAC,uBAAuB,IAAI,SAAS,CAAC;gBACzC,MAAM,CACJ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,aAAa,EACpC,SAAS,IAAI,KAAK,IAAI,+CAA+C,QAAQ,EAAE,CAChF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,aAAa,CAAC,IAAY,EAAE,KAAoB;QACrD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAChE,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAC/D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,SAAS;YACX,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,oCAAoC,IAAI,GAAG,CAAC;YAC5D,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC;YACtC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,MAAM,CACJ,MAAM,CAAC,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAC9D,OAAO,CACR,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,UAAU,CAAC,GAAW,EAAE,EAAU;QACvC,OAAO,IAAI,aAAa,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,iFAAiF;IACjF,uDAAuD;IACvD,MAAM,CAAC,mBAAmB,CACxB,UAAkB,EAClB,KAAW,EACX,KAAW,EACX,EAAU;QAEV,OAAO,UAAU,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC;aACzC,OAAO,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;aAC7C,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,oEAAoE;IACpE,MAAM,CAAC,sBAAsB,CAC3B,UAAkB,EAClB,KAAW,EACX,KAAW,EACX,EAAU;QAEV,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC;QAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC;QACvC,OAAO,KAAK,GAAG,KAAK,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC;oBAC3B,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC3D,KAAK,GAAG,OAAO,CAAC;gBAChB,SAAS;YACX,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAC5C,CAAC;YACD,KAAK,GAAG,KAAK,CAAC;YACd,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mBAAmB;IACnB,MAAM,CAAC,UAAU,CAAC,UAAkB,EAAE,EAAU;QAC9C,OAAO,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC"}
|
package/dist/rows.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type SqliteRow = Record<string, unknown>;
|
|
2
|
+
export declare class Row {
|
|
3
|
+
#private;
|
|
4
|
+
static parse(value: unknown, label: string): SqliteRow;
|
|
5
|
+
static readString(row: SqliteRow, column: string): string;
|
|
6
|
+
static readNullableString(row: SqliteRow, column: string): string | null;
|
|
7
|
+
static readNumber(row: SqliteRow, column: string): number;
|
|
8
|
+
static readNullableNumber(row: SqliteRow, column: string): number | null;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../src/rows.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,qBAAa,GAAG;;IAKd,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS;IAQtD,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IASzD,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAYxE,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IASzD,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAWzE"}
|
package/dist/rows.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export class Row {
|
|
2
|
+
static #isSqliteRow(value) {
|
|
3
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
static parse(value, label) {
|
|
6
|
+
if (!Row.#isSqliteRow(value)) {
|
|
7
|
+
throw new Error(`Expected SQLite row for ${label}`);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
static readString(row, column) {
|
|
12
|
+
const value = row[column];
|
|
13
|
+
if (typeof value !== 'string') {
|
|
14
|
+
throw new Error(`Expected string SQLite column: ${column}`);
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
static readNullableString(row, column) {
|
|
19
|
+
const value = row[column];
|
|
20
|
+
if (value === null) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (typeof value !== 'string') {
|
|
24
|
+
throw new Error(`Expected nullable string SQLite column: ${column}`);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
static readNumber(row, column) {
|
|
29
|
+
const value = row[column];
|
|
30
|
+
if (typeof value !== 'number') {
|
|
31
|
+
throw new Error(`Expected number SQLite column: ${column}`);
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
static readNullableNumber(row, column) {
|
|
36
|
+
const value = row[column];
|
|
37
|
+
if (value === null) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (typeof value !== 'number') {
|
|
41
|
+
throw new Error(`Expected nullable number SQLite column: ${column}`);
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=rows.js.map
|
package/dist/rows.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rows.js","sourceRoot":"","sources":["../src/rows.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAAG;IACd,MAAM,CAAC,YAAY,CAAC,KAAc;QAChC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,KAAc,EAAE,KAAa;QACxC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,GAAc,EAAE,MAAc;QAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,kBAAkB,CAAC,GAAc,EAAE,MAAc;QACtD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,GAAc,EAAE,MAAc;QAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,kBAAkB,CAAC,GAAc,EAAE,MAAc;QACtD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,eAAO,MAAM,WAAW,aAwIvB,CAAC"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Declaration } from '@zukhruf/sqlite-drift';
|
|
2
|
+
// The queue's tables and indexes. start() makes a file store them as declared
|
|
3
|
+
// and keeps the rows of each table it rebuilds, so the jobs and schedules of a
|
|
4
|
+
// file an earlier release made survive (docs/adr/0004).
|
|
5
|
+
export const queueSchema = new Declaration([
|
|
6
|
+
`CREATE TABLE pgboss_queue (
|
|
7
|
+
name TEXT PRIMARY KEY,
|
|
8
|
+
policy TEXT NOT NULL DEFAULT 'standard',
|
|
9
|
+
retry_limit INTEGER NOT NULL DEFAULT 2 CHECK (retry_limit >= 0),
|
|
10
|
+
retry_delay_seconds INTEGER NOT NULL DEFAULT 0 CHECK (retry_delay_seconds >= 0),
|
|
11
|
+
retry_backoff INTEGER NOT NULL DEFAULT 0 CHECK (retry_backoff IN (0, 1)),
|
|
12
|
+
retry_delay_max_seconds INTEGER CHECK (retry_delay_max_seconds IS NULL OR retry_delay_max_seconds >= 0),
|
|
13
|
+
expire_seconds INTEGER NOT NULL DEFAULT 900 CHECK (expire_seconds >= 1),
|
|
14
|
+
retention_seconds INTEGER NOT NULL DEFAULT 1209600 CHECK (retention_seconds >= 1),
|
|
15
|
+
deletion_seconds INTEGER NOT NULL DEFAULT 604800 CHECK (deletion_seconds >= 0),
|
|
16
|
+
heartbeat_seconds INTEGER CHECK (heartbeat_seconds IS NULL OR heartbeat_seconds >= 10),
|
|
17
|
+
-- queue_dead_letter_fkey (node_modules/pg-boss/dist/plans.js:321)
|
|
18
|
+
dead_letter TEXT REFERENCES pgboss_queue(name),
|
|
19
|
+
warning_queue_size INTEGER NOT NULL DEFAULT 0 CHECK (warning_queue_size >= 0),
|
|
20
|
+
notify INTEGER NOT NULL DEFAULT 0 CHECK (notify IN (0, 1)),
|
|
21
|
+
-- The monitor's counts and claim stamps (node_modules/pg-boss/dist/
|
|
22
|
+
-- plans.js:324-342); singletons_active is a JSON array of keys, nulls
|
|
23
|
+
-- included, or NULL when no singleton or stately job is active.
|
|
24
|
+
deferred_count INTEGER NOT NULL DEFAULT 0,
|
|
25
|
+
queued_count INTEGER NOT NULL DEFAULT 0,
|
|
26
|
+
ready_count INTEGER NOT NULL DEFAULT 0,
|
|
27
|
+
active_count INTEGER NOT NULL DEFAULT 0,
|
|
28
|
+
failed_count INTEGER NOT NULL DEFAULT 0,
|
|
29
|
+
total_count INTEGER NOT NULL DEFAULT 0,
|
|
30
|
+
singletons_active TEXT,
|
|
31
|
+
monitor_claim_on TEXT,
|
|
32
|
+
monitor_on TEXT,
|
|
33
|
+
maintain_on TEXT,
|
|
34
|
+
created_on TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
35
|
+
updated_on TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
36
|
+
)`,
|
|
37
|
+
`CREATE TABLE pgboss_job (
|
|
38
|
+
id TEXT NOT NULL,
|
|
39
|
+
queue_name TEXT NOT NULL REFERENCES pgboss_queue(name) ON DELETE CASCADE,
|
|
40
|
+
data TEXT NOT NULL DEFAULT '{}',
|
|
41
|
+
state TEXT NOT NULL DEFAULT 'created' CHECK (state IN ('created', 'retry', 'active', 'completed', 'cancelled', 'failed')),
|
|
42
|
+
-- A dead letter copy carries none (plans.js:2615-2643).
|
|
43
|
+
policy TEXT,
|
|
44
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
45
|
+
retry_limit INTEGER NOT NULL DEFAULT 2 CHECK (retry_limit >= 0),
|
|
46
|
+
retry_count INTEGER NOT NULL DEFAULT 0 CHECK (retry_count >= 0),
|
|
47
|
+
retry_delay_seconds INTEGER NOT NULL DEFAULT 0 CHECK (retry_delay_seconds >= 0),
|
|
48
|
+
retry_backoff INTEGER NOT NULL DEFAULT 0 CHECK (retry_backoff IN (0, 1)),
|
|
49
|
+
retry_delay_max_seconds INTEGER CHECK (retry_delay_max_seconds IS NULL OR retry_delay_max_seconds >= 0),
|
|
50
|
+
start_after TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
51
|
+
singleton_key TEXT,
|
|
52
|
+
singleton_on TEXT,
|
|
53
|
+
expire_seconds INTEGER NOT NULL DEFAULT 900 CHECK (expire_seconds >= 1),
|
|
54
|
+
retention_seconds INTEGER NOT NULL DEFAULT 1209600 CHECK (retention_seconds >= 1),
|
|
55
|
+
deletion_seconds INTEGER NOT NULL DEFAULT 604800 CHECK (deletion_seconds >= 0),
|
|
56
|
+
heartbeat_seconds INTEGER CHECK (heartbeat_seconds IS NULL OR heartbeat_seconds >= 10),
|
|
57
|
+
heartbeat_on TEXT,
|
|
58
|
+
lease_expires_on TEXT,
|
|
59
|
+
created_on TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
60
|
+
started_on TEXT,
|
|
61
|
+
completed_on TEXT,
|
|
62
|
+
keep_until TEXT NOT NULL,
|
|
63
|
+
cancelled_on TEXT,
|
|
64
|
+
failed_on TEXT,
|
|
65
|
+
output TEXT,
|
|
66
|
+
error TEXT,
|
|
67
|
+
-- dlq_fkey, RESTRICT (plans.js:878-881)
|
|
68
|
+
dead_letter TEXT REFERENCES pgboss_queue(name),
|
|
69
|
+
group_id TEXT,
|
|
70
|
+
group_tier TEXT,
|
|
71
|
+
source_name TEXT,
|
|
72
|
+
source_id TEXT,
|
|
73
|
+
source_created_on TEXT,
|
|
74
|
+
source_retry_count INTEGER,
|
|
75
|
+
source_output TEXT,
|
|
76
|
+
source_root_id TEXT,
|
|
77
|
+
-- pg-boss keys a job by queue and id (node_modules/pg-boss/dist/plans.js:
|
|
78
|
+
-- 871-880), so the same id may live in two queues.
|
|
79
|
+
PRIMARY KEY (queue_name, id)
|
|
80
|
+
)`,
|
|
81
|
+
`CREATE TABLE pgboss_schedule (
|
|
82
|
+
-- node_modules/pg-boss/dist/plans.js:358-374, without last_job_id.
|
|
83
|
+
queue_name TEXT NOT NULL REFERENCES pgboss_queue(name) ON DELETE CASCADE,
|
|
84
|
+
key TEXT NOT NULL DEFAULT '',
|
|
85
|
+
kind TEXT NOT NULL DEFAULT 'cron' CHECK (kind IN ('cron', 'rrule')),
|
|
86
|
+
cron TEXT NOT NULL,
|
|
87
|
+
timezone TEXT DEFAULT 'UTC',
|
|
88
|
+
data TEXT,
|
|
89
|
+
options TEXT,
|
|
90
|
+
created_on TEXT NOT NULL,
|
|
91
|
+
updated_on TEXT NOT NULL,
|
|
92
|
+
PRIMARY KEY (queue_name, key)
|
|
93
|
+
)`,
|
|
94
|
+
// The instance-wide cron claim, one row (node_modules/pg-boss/dist/
|
|
95
|
+
// plans.js:288-298, 1078-1086): when a pass last ran.
|
|
96
|
+
`CREATE TABLE pgboss_version (
|
|
97
|
+
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
98
|
+
cron_on TEXT
|
|
99
|
+
)`,
|
|
100
|
+
`CREATE INDEX pgboss_job_fetch_i
|
|
101
|
+
ON pgboss_job (queue_name, state, priority DESC, start_after, created_on)`,
|
|
102
|
+
`CREATE INDEX pgboss_job_lease_i
|
|
103
|
+
ON pgboss_job (lease_expires_on)
|
|
104
|
+
WHERE state = 'active' AND lease_expires_on IS NOT NULL`,
|
|
105
|
+
// pg-boss's policy and throttle indexes, each cited by its name and line in
|
|
106
|
+
// node_modules/pg-boss/dist/plans.js. Its `state <= active` compares enum
|
|
107
|
+
// order, which is created, retry, active.
|
|
108
|
+
// job_i1, plans.js:882
|
|
109
|
+
`CREATE UNIQUE INDEX pgboss_job_short_i
|
|
110
|
+
ON pgboss_job (queue_name, COALESCE(singleton_key, ''))
|
|
111
|
+
WHERE state = 'created' AND policy = 'short'`,
|
|
112
|
+
// job_i2, plans.js:885
|
|
113
|
+
`CREATE UNIQUE INDEX pgboss_job_singleton_i
|
|
114
|
+
ON pgboss_job (queue_name, COALESCE(singleton_key, ''))
|
|
115
|
+
WHERE state = 'active' AND policy = 'singleton'`,
|
|
116
|
+
// job_i3, plans.js:888
|
|
117
|
+
`CREATE UNIQUE INDEX pgboss_job_stately_i
|
|
118
|
+
ON pgboss_job (queue_name, state, COALESCE(singleton_key, ''))
|
|
119
|
+
WHERE state IN ('created', 'retry', 'active') AND policy = 'stately'`,
|
|
120
|
+
// job_i4, plans.js:891
|
|
121
|
+
`CREATE UNIQUE INDEX pgboss_job_throttle_i
|
|
122
|
+
ON pgboss_job (queue_name, singleton_on, COALESCE(singleton_key, ''))
|
|
123
|
+
WHERE state <> 'cancelled' AND singleton_on IS NOT NULL`,
|
|
124
|
+
// job_i6, plans.js:921
|
|
125
|
+
`CREATE UNIQUE INDEX pgboss_job_exclusive_i
|
|
126
|
+
ON pgboss_job (queue_name, COALESCE(singleton_key, ''))
|
|
127
|
+
WHERE state IN ('created', 'retry', 'active') AND policy = 'exclusive'`,
|
|
128
|
+
// job_i8, plans.js:924
|
|
129
|
+
`CREATE UNIQUE INDEX pgboss_job_key_strict_fifo_i
|
|
130
|
+
ON pgboss_job (queue_name, singleton_key)
|
|
131
|
+
WHERE state IN ('active', 'retry', 'failed') AND policy = 'key_strict_fifo'`,
|
|
132
|
+
// job_i10, plans.js:940: each key's queued jobs in head order, so a claim
|
|
133
|
+
// finds a key's head without scanning the queue. SQLite ends every index
|
|
134
|
+
// with rowid, the head order's tiebreak, where pg-boss's ends with id.
|
|
135
|
+
`CREATE INDEX pgboss_job_key_strict_fifo_heads_i
|
|
136
|
+
ON pgboss_job (queue_name, singleton_key, state DESC, created_on)
|
|
137
|
+
WHERE state IN ('created', 'retry') AND policy = 'key_strict_fifo'`,
|
|
138
|
+
], { rows: 'keep' });
|
|
139
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,8EAA8E;AAC9E,+EAA+E;AAC/E,wDAAwD;AACxD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,CACxC;IACE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8BA;IACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2CA;IACA;;;;;;;;;;;;IAYA;IACA,oEAAoE;IACpE,sDAAsD;IACtD;;;IAGA;IACA;8EAC0E;IAC1E;;4DAEwD;IACxD,4EAA4E;IAC5E,0EAA0E;IAC1E,0CAA0C;IAC1C,uBAAuB;IACvB;;iDAE6C;IAC7C,uBAAuB;IACvB;;oDAEgD;IAChD,uBAAuB;IACvB;;yEAEqE;IACrE,uBAAuB;IACvB;;4DAEwD;IACxD,uBAAuB;IACvB;;2EAEuE;IACvE,uBAAuB;IACvB;;gFAE4E;IAC5E,0EAA0E;IAC1E,yEAAyE;IACzE,uEAAuE;IACvE;;uEAEmE;CACpE,EACD,EAAE,IAAI,EAAE,MAAM,EAAE,CACjB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class SqlValues {
|
|
2
|
+
static asIso(value: Date): string;
|
|
3
|
+
static parseNullableDate(value: string | null | undefined): Date | null;
|
|
4
|
+
static addSeconds(date: Date, seconds: number): Date;
|
|
5
|
+
static plusSecondsSql(timestamp: string, seconds: string): string;
|
|
6
|
+
static text(value: unknown): string | null;
|
|
7
|
+
static toSqlBool(value: boolean | undefined): number | undefined;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=sql-values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-values.d.ts","sourceRoot":"","sources":["../src/sql-values.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAS;IACpB,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM;IAIjC,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI;IAIvE,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAMpD,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAOjE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAI1C,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS;CAGjE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class SqlValues {
|
|
2
|
+
static asIso(value) {
|
|
3
|
+
return value.toISOString();
|
|
4
|
+
}
|
|
5
|
+
static parseNullableDate(value) {
|
|
6
|
+
return value ? new Date(value) : null;
|
|
7
|
+
}
|
|
8
|
+
static addSeconds(date, seconds) {
|
|
9
|
+
return new Date(date.getTime() + seconds * 1000);
|
|
10
|
+
}
|
|
11
|
+
// A timestamp column plus a seconds column, in asIso's format, so it
|
|
12
|
+
// compares with an asIso value as text; SQLite keeps whole milliseconds.
|
|
13
|
+
static plusSecondsSql(timestamp, seconds) {
|
|
14
|
+
return `strftime('%Y-%m-%dT%H:%M:%fZ', ${timestamp}, '+' || ${seconds} || ' seconds')`;
|
|
15
|
+
}
|
|
16
|
+
// A text parameter as the oracle's driver binds it: a non-string as its
|
|
17
|
+
// String() (probed on PGlite: 0 as '0', false as 'false'), where node:sqlite
|
|
18
|
+
// would bind a number as REAL ('0.0').
|
|
19
|
+
static text(value) {
|
|
20
|
+
return value === null || value === undefined ? null : String(value);
|
|
21
|
+
}
|
|
22
|
+
static toSqlBool(value) {
|
|
23
|
+
return value === undefined ? undefined : value ? 1 : 0;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=sql-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-values.js","sourceRoot":"","sources":["../src/sql-values.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAS;IACpB,MAAM,CAAC,KAAK,CAAC,KAAW;QACtB,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,KAAgC;QACvD,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,IAAU,EAAE,OAAe;QAC3C,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,qEAAqE;IACrE,yEAAyE;IACzE,MAAM,CAAC,cAAc,CAAC,SAAiB,EAAE,OAAe;QACtD,OAAO,kCAAkC,SAAS,YAAY,OAAO,iBAAiB,CAAC;IACzF,CAAC;IAED,wEAAwE;IACxE,6EAA6E;IAC7E,uCAAuC;IACvC,MAAM,CAAC,IAAI,CAAC,KAAc;QACxB,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,KAA0B;QACzC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class UnsupportedStartAfterError extends Error {
|
|
2
|
+
name: string;
|
|
3
|
+
readonly startAfter: string;
|
|
4
|
+
constructor(startAfter: string);
|
|
5
|
+
}
|
|
6
|
+
export declare class StartAfter {
|
|
7
|
+
#private;
|
|
8
|
+
static resolve(value: unknown, now: Date): Date;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=start-after.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-after.d.ts","sourceRoot":"","sources":["../src/start-after.ts"],"names":[],"mappings":"AAEA,qBAAa,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,SAAgC;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,UAAU,EAAE,MAAM;CAM/B;AAcD,qBAAa,UAAU;;IAuCrB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI;CAqGhD"}
|