@go-avro/avro-js 0.0.45 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types/api/Job.d.ts +15 -0
- package/dist/types/api/Job.js +21 -0
- package/dist/types/api/Route.d.ts +13 -0
- package/dist/types/api/Route.js +32 -0
- package/dist/types/api/RouteJob.d.ts +7 -0
- package/dist/types/api/RouteJob.js +11 -0
- package/dist/types/api/Task.js +9 -6
- package/package.json +1 -1
package/dist/types/api/Job.d.ts
CHANGED
|
@@ -35,6 +35,21 @@ export declare class Job {
|
|
|
35
35
|
getOverdueLabel: () => string;
|
|
36
36
|
getStatus(): "PENDING_CUSTOMER" | "PENDING_COMPANY" | "ACTIVE" | "ARCHIVED" | "DRAFT" | "PENDING_PAYMENT" | "PENDING_ACTIVATION";
|
|
37
37
|
getStatusLabel(): "Active" | "Draft" | "Archived" | "Pending Activation" | "Customer Approval" | "Company Approval" | "Awaiting Payment";
|
|
38
|
+
/**
|
|
39
|
+
* Returns the sum of `service` (in seconds) for the tasks attached to a
|
|
40
|
+
* given routeJob. Use this to compute predicted completion time:
|
|
41
|
+
* `routeJob.getPredictedArrival() + job.getServiceDuration(routeJob)`.
|
|
42
|
+
*/
|
|
43
|
+
getServiceDuration: (routeJob: RouteJob) => number;
|
|
44
|
+
/**
|
|
45
|
+
* Returns the most relevant event for the job in its current state:
|
|
46
|
+
* the active `current_event` if one exists, otherwise the
|
|
47
|
+
* `last_completed_event`. Falls back to `null`.
|
|
48
|
+
*
|
|
49
|
+
* Most callers historically used `last_completed_event ?? current_event`
|
|
50
|
+
* which inverted the precedence — prefer the live event over a stale one.
|
|
51
|
+
*/
|
|
52
|
+
getRouteEvent: () => _Event | null;
|
|
38
53
|
portionDone: (route: Route) => number;
|
|
39
54
|
isDone: (route: Route) => boolean;
|
|
40
55
|
}
|
package/dist/types/api/Job.js
CHANGED
|
@@ -21,6 +21,27 @@ export class Job {
|
|
|
21
21
|
}, activeTasks[0]);
|
|
22
22
|
return mostOverdueTask.getOverdueLabel?.() ?? 'N/A';
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Returns the sum of `service` (in seconds) for the tasks attached to a
|
|
26
|
+
* given routeJob. Use this to compute predicted completion time:
|
|
27
|
+
* `routeJob.getPredictedArrival() + job.getServiceDuration(routeJob)`.
|
|
28
|
+
*/
|
|
29
|
+
this.getServiceDuration = (routeJob) => {
|
|
30
|
+
return routeJob.tasks
|
|
31
|
+
.map((tid) => this.tasks.find((t) => t.id === tid)?.service ?? 0)
|
|
32
|
+
.reduce((a, b) => a + b, 0);
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Returns the most relevant event for the job in its current state:
|
|
36
|
+
* the active `current_event` if one exists, otherwise the
|
|
37
|
+
* `last_completed_event`. Falls back to `null`.
|
|
38
|
+
*
|
|
39
|
+
* Most callers historically used `last_completed_event ?? current_event`
|
|
40
|
+
* which inverted the precedence — prefer the live event over a stale one.
|
|
41
|
+
*/
|
|
42
|
+
this.getRouteEvent = () => {
|
|
43
|
+
return this.current_event ?? this.last_completed_event ?? null;
|
|
44
|
+
};
|
|
24
45
|
this.portionDone = (route) => {
|
|
25
46
|
if (!this.tasks || this.tasks.length === 0) {
|
|
26
47
|
return 0;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RouteJob } from '../../types/api/RouteJob';
|
|
2
|
+
import type { Job } from '../../types/api/Job';
|
|
2
3
|
export declare const FrequencyType: {
|
|
3
4
|
readonly ONCE: "ONCE";
|
|
4
5
|
readonly DAILY: "DAILY";
|
|
@@ -33,4 +34,16 @@ export declare class Route {
|
|
|
33
34
|
constructor(init?: Partial<Route>);
|
|
34
35
|
getNextOccurrences: (count?: number) => (Date | null)[];
|
|
35
36
|
getNextOccurrence: (after?: Date) => Date | null;
|
|
37
|
+
/**
|
|
38
|
+
* Computes how far ahead/behind schedule the route is, in seconds, based on
|
|
39
|
+
* stops that have already been completed. Positive = behind schedule,
|
|
40
|
+
* negative = ahead of schedule.
|
|
41
|
+
*
|
|
42
|
+
* The offset is taken from the most recently completed stop (largest
|
|
43
|
+
* `time_ended`), not the last stop in route order. This is what consumers
|
|
44
|
+
* want: "given the latest completed work, how off-schedule are we?".
|
|
45
|
+
*
|
|
46
|
+
* Returns `null` if no stop in this route has a usable completion event.
|
|
47
|
+
*/
|
|
48
|
+
getScheduleOffset: (jobs: Job[]) => number | null;
|
|
36
49
|
}
|
package/dist/types/api/Route.js
CHANGED
|
@@ -43,6 +43,38 @@ export class Route {
|
|
|
43
43
|
}
|
|
44
44
|
return next_occurrence;
|
|
45
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* Computes how far ahead/behind schedule the route is, in seconds, based on
|
|
48
|
+
* stops that have already been completed. Positive = behind schedule,
|
|
49
|
+
* negative = ahead of schedule.
|
|
50
|
+
*
|
|
51
|
+
* The offset is taken from the most recently completed stop (largest
|
|
52
|
+
* `time_ended`), not the last stop in route order. This is what consumers
|
|
53
|
+
* want: "given the latest completed work, how off-schedule are we?".
|
|
54
|
+
*
|
|
55
|
+
* Returns `null` if no stop in this route has a usable completion event.
|
|
56
|
+
*/
|
|
57
|
+
this.getScheduleOffset = (jobs) => {
|
|
58
|
+
let latestEnd = -Infinity;
|
|
59
|
+
let offset = null;
|
|
60
|
+
for (const rj of this.jobs) {
|
|
61
|
+
const job = jobs.find((j) => j.id === rj.job_id);
|
|
62
|
+
if (!job || !job.isDone(this))
|
|
63
|
+
continue;
|
|
64
|
+
// Offset semantics specifically want a *completed* event, not an
|
|
65
|
+
// in-progress one. Use last_completed_event directly rather than
|
|
66
|
+
// getRouteEvent() (which prefers current_event for display).
|
|
67
|
+
const actualEnd = job.last_completed_event?.time_ended;
|
|
68
|
+
if (typeof actualEnd !== 'number' || actualEnd <= 0)
|
|
69
|
+
continue;
|
|
70
|
+
if (actualEnd <= latestEnd)
|
|
71
|
+
continue;
|
|
72
|
+
const predictedCompletion = rj.getPredictedArrival() + job.getServiceDuration(rj);
|
|
73
|
+
latestEnd = actualEnd;
|
|
74
|
+
offset = actualEnd - predictedCompletion;
|
|
75
|
+
}
|
|
76
|
+
return offset;
|
|
77
|
+
};
|
|
46
78
|
Object.assign(this, init);
|
|
47
79
|
if (init?.jobs) {
|
|
48
80
|
this.jobs = init.jobs.map((j) => new RouteJob(j));
|
|
@@ -12,4 +12,11 @@ declare module '../../types/api/RouteJob' {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class RouteJob {
|
|
14
14
|
constructor(init?: Partial<RouteJob>);
|
|
15
|
+
/**
|
|
16
|
+
* Returns the arrival time the UI should show for this stop:
|
|
17
|
+
* `scheduled_arrival_time` if set (>= 0), otherwise the optimizer's
|
|
18
|
+
* `estimated_arrival_time`. The sentinel value -1 means "no manual
|
|
19
|
+
* schedule, fall back to the optimizer estimate".
|
|
20
|
+
*/
|
|
21
|
+
getPredictedArrival: () => number;
|
|
15
22
|
}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
export class RouteJob {
|
|
2
2
|
constructor(init) {
|
|
3
|
+
/**
|
|
4
|
+
* Returns the arrival time the UI should show for this stop:
|
|
5
|
+
* `scheduled_arrival_time` if set (>= 0), otherwise the optimizer's
|
|
6
|
+
* `estimated_arrival_time`. The sentinel value -1 means "no manual
|
|
7
|
+
* schedule, fall back to the optimizer estimate".
|
|
8
|
+
*/
|
|
9
|
+
this.getPredictedArrival = () => {
|
|
10
|
+
return this.scheduled_arrival_time === -1
|
|
11
|
+
? this.estimated_arrival_time
|
|
12
|
+
: this.scheduled_arrival_time;
|
|
13
|
+
};
|
|
3
14
|
Object.assign(this, init);
|
|
4
15
|
}
|
|
5
16
|
}
|
package/dist/types/api/Task.js
CHANGED
|
@@ -102,12 +102,15 @@ export class Task {
|
|
|
102
102
|
if (!this.status || this.status !== TaskStatus.ACTIVE) {
|
|
103
103
|
return true;
|
|
104
104
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
// Cutoff: midnight (local time) of the day route.start_time falls on.
|
|
106
|
+
// Counts work completed at any point during the route's day (including
|
|
107
|
+
// an early-start autostart that finishes a few minutes before
|
|
108
|
+
// route.start_time) while still rejecting stale events from previous
|
|
109
|
+
// occurrences. Applies to both recurring and one-shot tasks.
|
|
110
|
+
const routeDay = new Date(route.start_time * 1000);
|
|
111
|
+
routeDay.setHours(0, 0, 0, 0);
|
|
112
|
+
const cutoff = Math.floor(routeDay.getTime() / 1000);
|
|
113
|
+
return (this.last_completed_event?.time_ended ?? 0) >= cutoff;
|
|
111
114
|
};
|
|
112
115
|
Object.assign(this, init);
|
|
113
116
|
if (init?.prepayments) {
|