@knpkv/herdr-work 0.4.0 → 0.5.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.
- package/README.md +95 -1
- package/dist/agent-binding.d.ts +4 -0
- package/dist/agent-binding.d.ts.map +1 -0
- package/dist/agent-binding.js +26 -0
- package/dist/agent-binding.js.map +1 -0
- package/dist/errors.d.ts +141 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +97 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/agent-binding-admission.d.ts +15 -0
- package/dist/internal/agent-binding-admission.d.ts.map +1 -0
- package/dist/internal/agent-binding-admission.js +92 -0
- package/dist/internal/agent-binding-admission.js.map +1 -0
- package/dist/internal/agent-binding-readback.d.ts +55 -0
- package/dist/internal/agent-binding-readback.d.ts.map +1 -0
- package/dist/internal/agent-binding-readback.js +124 -0
- package/dist/internal/agent-binding-readback.js.map +1 -0
- package/dist/internal/coordinator-authority.d.ts +62 -0
- package/dist/internal/coordinator-authority.d.ts.map +1 -0
- package/dist/internal/coordinator-authority.js +214 -0
- package/dist/internal/coordinator-authority.js.map +1 -0
- package/dist/internal/decision-handoff-migration.d.ts +126 -0
- package/dist/internal/decision-handoff-migration.d.ts.map +1 -0
- package/dist/internal/decision-handoff-migration.js +51 -0
- package/dist/internal/decision-handoff-migration.js.map +1 -0
- package/dist/internal/history-validation.d.ts +5 -0
- package/dist/internal/history-validation.d.ts.map +1 -0
- package/dist/internal/history-validation.js +33 -0
- package/dist/internal/history-validation.js.map +1 -0
- package/dist/model.d.ts +3075 -51
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +334 -12
- package/dist/model.js.map +1 -1
- package/dist/navigation.d.ts +17 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +62 -0
- package/dist/navigation.js.map +1 -0
- package/dist/projection.d.ts +644 -0
- package/dist/projection.d.ts.map +1 -1
- package/dist/projection.js +65 -30
- package/dist/projection.js.map +1 -1
- package/dist/service.d.ts +1870 -3
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +138 -5
- package/dist/service.js.map +1 -1
- package/dist/sql.d.ts +30 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +1454 -0
- package/dist/sql.js.map +1 -0
- package/dist/store.d.ts +1068 -4
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +3275 -51
- package/dist/store.js.map +1 -1
- package/dist/view.d.ts.map +1 -1
- package/dist/view.js +154 -8
- package/dist/view.js.map +1 -1
- package/package.json +25 -13
- package/src/styles.css +91 -17
package/dist/projection.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
2
|
import { WorkProjectionError } from "./errors.js";
|
|
3
|
-
import {
|
|
3
|
+
import { workHistoryError } from "./internal/history-validation.js";
|
|
4
4
|
import { WorkGoalCheckpoint, workHistoryMaxEvents, WorkSnapshots } from "./model.js";
|
|
5
5
|
const windowOffset = {
|
|
6
6
|
now: 0,
|
|
@@ -8,39 +8,59 @@ const windowOffset = {
|
|
|
8
8
|
week: 7 * 24 * 60 * 60 * 1_000,
|
|
9
9
|
month: 30 * 24 * 60 * 60 * 1_000
|
|
10
10
|
};
|
|
11
|
+
const compareString = (left, right) => {
|
|
12
|
+
let li = 0;
|
|
13
|
+
let ri = 0;
|
|
14
|
+
const leftLength = left.length;
|
|
15
|
+
const rightLength = right.length;
|
|
16
|
+
while (li < leftLength && ri < rightLength) {
|
|
17
|
+
const leftCode = left.codePointAt(li);
|
|
18
|
+
const rightCode = right.codePointAt(ri);
|
|
19
|
+
if (leftCode === undefined || rightCode === undefined)
|
|
20
|
+
break;
|
|
21
|
+
if (leftCode !== rightCode)
|
|
22
|
+
return leftCode < rightCode ? -1 : 1;
|
|
23
|
+
li += leftCode > 0xffff ? 2 : 1;
|
|
24
|
+
ri += rightCode > 0xffff ? 2 : 1;
|
|
25
|
+
}
|
|
26
|
+
if (li >= leftLength && ri >= rightLength)
|
|
27
|
+
return 0;
|
|
28
|
+
return li >= leftLength ? -1 : 1;
|
|
29
|
+
};
|
|
11
30
|
const projectionError = (reason, detail, cause) => new WorkProjectionError({ cause, detail, reason });
|
|
12
31
|
const validateHistory = Effect.fn("HerdrWork.validateHistory")(function* (input) {
|
|
13
32
|
const events = yield* Schema.decodeUnknownEffect(Schema.Array(WorkGoalCheckpoint).check(Schema.isMaxLength(workHistoryMaxEvents)))(input).pipe(Effect.mapError((cause) => projectionError("malformed", "work checkpoint history is malformed", cause)));
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const ordered = events.toSorted((left, right) => left.occurredAt - right.occurredAt);
|
|
18
|
-
for (const event of ordered) {
|
|
19
|
-
if (eventIds.has(event.eventId)) {
|
|
20
|
-
return yield* projectionError("duplicate_event", `work event ${event.eventId} occurs more than once`, event);
|
|
21
|
-
}
|
|
22
|
-
eventIds.add(event.eventId);
|
|
23
|
-
const timeKey = `${event.goal.id}\u0000${event.occurredAt}`;
|
|
24
|
-
if (goalTimes.has(timeKey)) {
|
|
25
|
-
return yield* projectionError("ambiguous_checkpoint", `goal ${event.goal.id} has more than one checkpoint at ${event.occurredAt}`, event);
|
|
26
|
-
}
|
|
27
|
-
goalTimes.add(timeKey);
|
|
28
|
-
const firstCreatedAt = createdAt.get(event.goal.id);
|
|
29
|
-
if (firstCreatedAt !== undefined && firstCreatedAt !== event.goal.createdAt) {
|
|
30
|
-
return yield* projectionError("inconsistent_history", `goal ${event.goal.id} changed its creation timestamp`, event);
|
|
31
|
-
}
|
|
32
|
-
createdAt.set(event.goal.id, event.goal.createdAt);
|
|
33
|
-
}
|
|
34
|
-
for (const [goalId, timestamp] of createdAt) {
|
|
35
|
-
if (!events.some((event) => event.goal.id === goalId && event.occurredAt === timestamp)) {
|
|
36
|
-
return yield* projectionError("inconsistent_history", `goal ${goalId} has no checkpoint at its creation timestamp`, { goalId, timestamp });
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
const familyError = validateGoalFamilyHistory(events);
|
|
40
|
-
if (familyError !== undefined)
|
|
41
|
-
return yield* familyError;
|
|
33
|
+
const historyError = workHistoryError(events);
|
|
34
|
+
if (historyError !== undefined)
|
|
35
|
+
return yield* historyError;
|
|
42
36
|
return events;
|
|
43
37
|
});
|
|
38
|
+
const familiesFor = (latest) => {
|
|
39
|
+
const canonicalById = new Map();
|
|
40
|
+
for (const goal of latest.values()) {
|
|
41
|
+
if (goal.goalFamily?.role === "canonical")
|
|
42
|
+
canonicalById.set(goal.id, goal);
|
|
43
|
+
}
|
|
44
|
+
const groups = [];
|
|
45
|
+
for (const canonical of canonicalById.values()) {
|
|
46
|
+
const superseded = [...latest.values()]
|
|
47
|
+
.filter((goal) => goal.goalFamily?.role === "superseded" &&
|
|
48
|
+
goal.goalFamily.canonicalGoalId === canonical.id)
|
|
49
|
+
.toSorted((left, right) => right.updatedAt - left.updatedAt ||
|
|
50
|
+
compareString(left.title, right.title) ||
|
|
51
|
+
compareString(left.id, right.id));
|
|
52
|
+
if (superseded.length === 0)
|
|
53
|
+
continue;
|
|
54
|
+
groups.push({
|
|
55
|
+
canonicalGoalId: canonical.id,
|
|
56
|
+
canonical,
|
|
57
|
+
superseded
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return groups.toSorted((left, right) => right.canonical.updatedAt - left.canonical.updatedAt ||
|
|
61
|
+
compareString(left.canonical.title, right.canonical.title) ||
|
|
62
|
+
compareString(left.canonicalGoalId, right.canonicalGoalId));
|
|
63
|
+
};
|
|
44
64
|
const snapshotAt = (events, observedAt, window) => {
|
|
45
65
|
const asOf = Math.max(0, observedAt - windowOffset[window]);
|
|
46
66
|
const latest = new Map();
|
|
@@ -48,11 +68,26 @@ const snapshotAt = (events, observedAt, window) => {
|
|
|
48
68
|
if (event.occurredAt <= asOf)
|
|
49
69
|
latest.set(event.goal.id, event.goal);
|
|
50
70
|
}
|
|
71
|
+
const families = familiesFor(latest);
|
|
72
|
+
const goals = [...latest.values()]
|
|
73
|
+
.filter((goal) => goal.goalFamily?.role !== "superseded")
|
|
74
|
+
.toSorted((left, right) => right.updatedAt - left.updatedAt ||
|
|
75
|
+
compareString(left.title, right.title) ||
|
|
76
|
+
compareString(left.id, right.id));
|
|
77
|
+
if (families.length > 0) {
|
|
78
|
+
return {
|
|
79
|
+
window,
|
|
80
|
+
observedAt,
|
|
81
|
+
asOf,
|
|
82
|
+
goals,
|
|
83
|
+
families
|
|
84
|
+
};
|
|
85
|
+
}
|
|
51
86
|
return {
|
|
52
87
|
window,
|
|
53
88
|
observedAt,
|
|
54
89
|
asOf,
|
|
55
|
-
goals
|
|
90
|
+
goals
|
|
56
91
|
};
|
|
57
92
|
};
|
|
58
93
|
export const projectWorkSnapshots = Effect.fn("HerdrWork.projectSnapshots")(function* (input, observedAt) {
|
package/dist/projection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.js","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"projection.js","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"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"}
|