@ixo/topic-protocol 0.3.0 → 0.5.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/README.md +9 -3
- package/dist/schemas/topic-contract-state.schema.json +292 -0
- package/dist/schemas/topic-file-attachment.schema.json +1 -1
- package/dist/schemas/topic-index-entry.schema.json +34 -1
- package/dist/schemas/topic-index.schema.json +39 -0
- package/dist/schemas/topic-operation.schema.json +14 -3
- package/dist/schemas/topic-preferences.schema.json +47 -2
- package/dist/schemas/topic-root.schema.json +9 -3
- package/dist/src/contracts/schemas.d.ts +916 -4
- package/dist/src/contracts/schemas.js +4 -0
- package/dist/src/contracts/schemas.js.map +1 -1
- package/dist/src/contracts/topic-contract.d.ts +149 -0
- package/dist/src/contracts/topic-contract.js +104 -0
- package/dist/src/contracts/topic-contract.js.map +1 -0
- package/dist/src/index.d.ts +7 -2
- package/dist/src/index.js +6 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/indexing/rank.d.ts +2 -0
- package/dist/src/indexing/rank.js +31 -0
- package/dist/src/indexing/rank.js.map +1 -0
- package/dist/src/indexing/reconcile.d.ts +3 -0
- package/dist/src/indexing/reconcile.js +58 -0
- package/dist/src/indexing/reconcile.js.map +1 -0
- package/dist/src/indexing/search.d.ts +2 -0
- package/dist/src/indexing/search.js +37 -0
- package/dist/src/indexing/search.js.map +1 -0
- package/dist/src/indexing/types.d.ts +76 -0
- package/dist/src/indexing/types.js +22 -0
- package/dist/src/indexing/types.js.map +1 -0
- package/dist/src/matrix/anchors.d.ts +3 -0
- package/dist/src/matrix/anchors.js +14 -0
- package/dist/src/matrix/anchors.js.map +1 -1
- package/dist/src/projector/payload.d.ts +19 -1
- package/dist/src/projector/payload.js +74 -0
- package/dist/src/projector/payload.js.map +1 -1
- package/dist/src/projector/state.js +47 -0
- package/dist/src/projector/state.js.map +1 -1
- package/dist/src/projector/types.d.ts +49 -6
- package/dist/src/projector/types.js +3 -0
- package/dist/src/projector/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,8 +3,10 @@ import agentRun from "../../schemas/agent-run.schema.json" with { type: "json" }
|
|
|
3
3
|
import externalSessionBinding from "../../schemas/external-session-binding.schema.json" with { type: "json" };
|
|
4
4
|
import roomPolicy from "../../schemas/room-policy.schema.json" with { type: "json" };
|
|
5
5
|
import topicCapsule from "../../schemas/topic-capsule.schema.json" with { type: "json" };
|
|
6
|
+
import topicContractState from "../../schemas/topic-contract-state.schema.json" with { type: "json" };
|
|
6
7
|
import topicFileAttachment from "../../schemas/topic-file-attachment.schema.json" with { type: "json" };
|
|
7
8
|
import topicIndexEntry from "../../schemas/topic-index-entry.schema.json" with { type: "json" };
|
|
9
|
+
import topicIndex from "../../schemas/topic-index.schema.json" with { type: "json" };
|
|
8
10
|
import topicMessage from "../../schemas/topic-message.schema.json" with { type: "json" };
|
|
9
11
|
import topicOperation from "../../schemas/topic-operation.schema.json" with { type: "json" };
|
|
10
12
|
import topicPreferences from "../../schemas/topic-preferences.schema.json" with { type: "json" };
|
|
@@ -20,8 +22,10 @@ export const SCHEMA_REGISTRY = Object.freeze({
|
|
|
20
22
|
"external-session-binding": externalSessionBinding,
|
|
21
23
|
"room-policy": roomPolicy,
|
|
22
24
|
"topic-capsule": topicCapsule,
|
|
25
|
+
"topic-contract-state": topicContractState,
|
|
23
26
|
"topic-file-attachment": topicFileAttachment,
|
|
24
27
|
"topic-index-entry": topicIndexEntry,
|
|
28
|
+
"topic-index": topicIndex,
|
|
25
29
|
"topic-message": topicMessage,
|
|
26
30
|
"topic-operation": topicOperation,
|
|
27
31
|
"topic-preferences": topicPreferences,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/contracts/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,0CAA0C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3F,OAAO,QAAQ,MAAM,qCAAqC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjF,OAAO,sBAAsB,MAAM,oDAAoD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9G,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,YAAY,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,mBAAmB,MAAM,iDAAiD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACxG,OAAO,eAAe,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChG,OAAO,YAAY,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,cAAc,MAAM,2CAA2C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC7F,OAAO,gBAAgB,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjG,OAAO,WAAW,MAAM,wCAAwC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACvF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACtG,OAAO,aAAa,MAAM,0CAA0C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3F,OAAO,SAAS,MAAM,sCAAsC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACnF,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEtG,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,gBAAgB,EAAE,aAAa;IAC/B,WAAW,EAAE,QAAQ;IACrB,0BAA0B,EAAE,sBAAsB;IAClD,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,YAAY;IAC7B,uBAAuB,EAAE,mBAAmB;IAC5C,mBAAmB,EAAE,eAAe;IACpC,eAAe,EAAE,YAAY;IAC7B,iBAAiB,EAAE,cAAc;IACjC,mBAAmB,EAAE,gBAAgB;IACrC,cAAc,EAAE,WAAW;IAC3B,sBAAsB,EAAE,kBAAkB;IAC1C,gBAAgB,EAAE,aAAa;IAC/B,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,UAAU;IACzB,sBAAsB,EAAE,kBAAkB;CAC3C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CACzC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,EAAoB,CACtD,CAAC"}
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/contracts/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,0CAA0C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3F,OAAO,QAAQ,MAAM,qCAAqC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjF,OAAO,sBAAsB,MAAM,oDAAoD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9G,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,YAAY,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACtG,OAAO,mBAAmB,MAAM,iDAAiD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACxG,OAAO,eAAe,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChG,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,YAAY,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,cAAc,MAAM,2CAA2C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC7F,OAAO,gBAAgB,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjG,OAAO,WAAW,MAAM,wCAAwC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACvF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACtG,OAAO,aAAa,MAAM,0CAA0C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3F,OAAO,SAAS,MAAM,sCAAsC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACnF,OAAO,UAAU,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrF,OAAO,kBAAkB,MAAM,gDAAgD,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEtG,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,gBAAgB,EAAE,aAAa;IAC/B,WAAW,EAAE,QAAQ;IACrB,0BAA0B,EAAE,sBAAsB;IAClD,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,YAAY;IAC7B,sBAAsB,EAAE,kBAAkB;IAC1C,uBAAuB,EAAE,mBAAmB;IAC5C,mBAAmB,EAAE,eAAe;IACpC,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,YAAY;IAC7B,iBAAiB,EAAE,cAAc;IACjC,mBAAmB,EAAE,gBAAgB;IACrC,cAAc,EAAE,WAAW;IAC3B,sBAAsB,EAAE,kBAAkB;IAC1C,gBAAgB,EAAE,aAAa;IAC/B,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,UAAU;IACzB,sBAAsB,EAAE,kBAAkB;CAC3C,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CACzC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,EAAoB,CACtD,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export declare const PERSISTED_TOPIC_KINDS: readonly ["task", "agent_task", "proposal", "evaluation", "claims", "question", "discussion", "incident"];
|
|
2
|
+
export declare const TOPIC_CONTRACT_RECIPES: readonly ["project", "flow", "proposal", "evaluation", "claims", "research", "discussion", "incident"];
|
|
3
|
+
export type PersistedTopicKind = (typeof PERSISTED_TOPIC_KINDS)[number];
|
|
4
|
+
export type TopicContractRecipe = (typeof TOPIC_CONTRACT_RECIPES)[number];
|
|
5
|
+
export type TopicKindRef = {
|
|
6
|
+
readonly source: "standard";
|
|
7
|
+
readonly kind: PersistedTopicKind;
|
|
8
|
+
} | {
|
|
9
|
+
readonly source: "custom";
|
|
10
|
+
readonly customId: string;
|
|
11
|
+
readonly label: string;
|
|
12
|
+
readonly baseKind: PersistedTopicKind;
|
|
13
|
+
};
|
|
14
|
+
export type TopicIconName = "task" | "agent" | "proposal" | "evaluation" | "claims" | "question" | "discussion" | "incident";
|
|
15
|
+
export type TopicAppearance = {
|
|
16
|
+
readonly glyph?: {
|
|
17
|
+
readonly type: "emoji";
|
|
18
|
+
readonly value: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly type: "icon";
|
|
21
|
+
readonly name: TopicIconName;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export interface TopicStatementV2 {
|
|
25
|
+
readonly id: string;
|
|
26
|
+
readonly text: string;
|
|
27
|
+
readonly provenance: {
|
|
28
|
+
readonly basis: "explicit" | "contextual" | "inferred" | "suggested" | "retrieved";
|
|
29
|
+
readonly acceptance: "proposed" | "accepted" | "rejected" | "superseded";
|
|
30
|
+
readonly sourceEventIds: readonly string[];
|
|
31
|
+
readonly createdBy?: string;
|
|
32
|
+
readonly createdAt?: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export type TemporalTarget = {
|
|
36
|
+
readonly precision: "date";
|
|
37
|
+
readonly value: string;
|
|
38
|
+
readonly timezone: string;
|
|
39
|
+
} | {
|
|
40
|
+
readonly precision: "datetime";
|
|
41
|
+
readonly value: string;
|
|
42
|
+
readonly timezone: string;
|
|
43
|
+
};
|
|
44
|
+
export interface TopicRiskV2 {
|
|
45
|
+
readonly id: string;
|
|
46
|
+
readonly description: string;
|
|
47
|
+
readonly impact?: "low" | "medium" | "high" | "critical";
|
|
48
|
+
readonly status: "open" | "mitigated" | "accepted" | "closed";
|
|
49
|
+
readonly owner?: string;
|
|
50
|
+
readonly mitigation?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface TopicOutcomeV2 {
|
|
53
|
+
readonly statement?: TopicStatementV2;
|
|
54
|
+
readonly status?: "proposed" | "accepted" | "achieved" | "abandoned";
|
|
55
|
+
readonly target?: TemporalTarget;
|
|
56
|
+
readonly successCriteria?: readonly {
|
|
57
|
+
readonly id: string;
|
|
58
|
+
readonly description: string;
|
|
59
|
+
readonly status: "pending" | "met" | "not_met" | "waived";
|
|
60
|
+
readonly verification?: {
|
|
61
|
+
readonly method: "human" | "agent" | "oracle" | "claim" | "artifact" | "custom";
|
|
62
|
+
readonly evaluator?: string;
|
|
63
|
+
readonly evidenceRequired?: readonly string[];
|
|
64
|
+
};
|
|
65
|
+
}[];
|
|
66
|
+
readonly outcomeRecordId?: string;
|
|
67
|
+
readonly abandonedReason?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface TopicContractBodyV2 {
|
|
70
|
+
readonly version: 2;
|
|
71
|
+
readonly revision: string;
|
|
72
|
+
readonly status: "draft" | "accepted" | "superseded";
|
|
73
|
+
readonly kindRef: TopicKindRef;
|
|
74
|
+
readonly authoredBy: string;
|
|
75
|
+
readonly authoredAt: string;
|
|
76
|
+
readonly workingMode: "solo" | "team" | "client";
|
|
77
|
+
readonly recipe: TopicContractRecipe;
|
|
78
|
+
readonly locale?: string;
|
|
79
|
+
readonly timezone?: string;
|
|
80
|
+
readonly temporalMode?: "finite" | "ongoing";
|
|
81
|
+
readonly tags?: readonly string[];
|
|
82
|
+
readonly appearance?: TopicAppearance;
|
|
83
|
+
readonly intent?: TopicStatementV2;
|
|
84
|
+
readonly outcome?: TopicOutcomeV2;
|
|
85
|
+
readonly completion?: {
|
|
86
|
+
readonly definition?: string;
|
|
87
|
+
readonly acceptanceAuthorityIds?: readonly string[];
|
|
88
|
+
readonly requiresOutcomeRecord?: boolean;
|
|
89
|
+
readonly reviewAt?: string;
|
|
90
|
+
};
|
|
91
|
+
readonly ownerId?: string;
|
|
92
|
+
readonly scope?: {
|
|
93
|
+
readonly included?: readonly TopicStatementV2[];
|
|
94
|
+
readonly excluded?: readonly TopicStatementV2[];
|
|
95
|
+
};
|
|
96
|
+
readonly constraints?: readonly TopicStatementV2[];
|
|
97
|
+
readonly assumptions?: readonly Readonly<Record<string, unknown>>[];
|
|
98
|
+
readonly questions?: readonly Readonly<Record<string, unknown>>[];
|
|
99
|
+
readonly risks?: readonly TopicRiskV2[];
|
|
100
|
+
readonly participants?: readonly Readonly<Record<string, unknown>>[];
|
|
101
|
+
readonly roles?: readonly Readonly<Record<string, unknown>>[];
|
|
102
|
+
readonly agents?: readonly Readonly<Record<string, unknown>>[];
|
|
103
|
+
readonly decision?: Readonly<Record<string, unknown>>;
|
|
104
|
+
readonly plan?: Readonly<Record<string, unknown>>;
|
|
105
|
+
readonly attachments?: readonly Readonly<Record<string, unknown>>[];
|
|
106
|
+
}
|
|
107
|
+
export type TopicReminder = {
|
|
108
|
+
readonly mode: "at";
|
|
109
|
+
readonly at: string;
|
|
110
|
+
readonly timezone: string;
|
|
111
|
+
} | {
|
|
112
|
+
readonly mode: "before_due";
|
|
113
|
+
readonly minutes: number;
|
|
114
|
+
};
|
|
115
|
+
export interface TopicUserSettings {
|
|
116
|
+
readonly companion?: {
|
|
117
|
+
readonly oracleDid: string;
|
|
118
|
+
readonly sessionId: string;
|
|
119
|
+
readonly lastContextRevision?: string;
|
|
120
|
+
};
|
|
121
|
+
readonly reminder?: TopicReminder;
|
|
122
|
+
}
|
|
123
|
+
export type Weekday = "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday";
|
|
124
|
+
export type TopicRecurrence = {
|
|
125
|
+
readonly frequency: "daily";
|
|
126
|
+
readonly time: string;
|
|
127
|
+
readonly timezone: string;
|
|
128
|
+
} | {
|
|
129
|
+
readonly frequency: "weekly";
|
|
130
|
+
readonly days: readonly Weekday[];
|
|
131
|
+
readonly time: string;
|
|
132
|
+
readonly timezone: string;
|
|
133
|
+
};
|
|
134
|
+
export interface TopicAutomationBindingV2 {
|
|
135
|
+
readonly provider: "temporal";
|
|
136
|
+
readonly scheduleId: string;
|
|
137
|
+
readonly actionId: string;
|
|
138
|
+
readonly recurrence: TopicRecurrence;
|
|
139
|
+
readonly status: "pending" | "active" | "paused" | "failed";
|
|
140
|
+
readonly nextRunAt?: string;
|
|
141
|
+
}
|
|
142
|
+
export declare function baseTopicKind(kindRef: TopicKindRef): PersistedTopicKind;
|
|
143
|
+
export declare function topicRecipeForKind(kindRef: TopicKindRef): TopicContractRecipe;
|
|
144
|
+
export interface TopicContractCompletenessIssue {
|
|
145
|
+
readonly path: string;
|
|
146
|
+
readonly message: string;
|
|
147
|
+
}
|
|
148
|
+
export declare function contractCompleteness(body: TopicContractBodyV2): readonly TopicContractCompletenessIssue[];
|
|
149
|
+
export declare function assertContractComplete(body: TopicContractBodyV2): void;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { TopicProtocolError } from "../errors.js";
|
|
2
|
+
export const PERSISTED_TOPIC_KINDS = [
|
|
3
|
+
"task",
|
|
4
|
+
"agent_task",
|
|
5
|
+
"proposal",
|
|
6
|
+
"evaluation",
|
|
7
|
+
"claims",
|
|
8
|
+
"question",
|
|
9
|
+
"discussion",
|
|
10
|
+
"incident",
|
|
11
|
+
];
|
|
12
|
+
export const TOPIC_CONTRACT_RECIPES = [
|
|
13
|
+
"project",
|
|
14
|
+
"flow",
|
|
15
|
+
"proposal",
|
|
16
|
+
"evaluation",
|
|
17
|
+
"claims",
|
|
18
|
+
"research",
|
|
19
|
+
"discussion",
|
|
20
|
+
"incident",
|
|
21
|
+
];
|
|
22
|
+
const RECIPE_BY_KIND = {
|
|
23
|
+
task: "project",
|
|
24
|
+
agent_task: "flow",
|
|
25
|
+
proposal: "proposal",
|
|
26
|
+
evaluation: "evaluation",
|
|
27
|
+
claims: "claims",
|
|
28
|
+
question: "research",
|
|
29
|
+
discussion: "discussion",
|
|
30
|
+
incident: "incident",
|
|
31
|
+
};
|
|
32
|
+
export function baseTopicKind(kindRef) {
|
|
33
|
+
return kindRef.source === "standard" ? kindRef.kind : kindRef.baseKind;
|
|
34
|
+
}
|
|
35
|
+
export function topicRecipeForKind(kindRef) {
|
|
36
|
+
return RECIPE_BY_KIND[baseTopicKind(kindRef)];
|
|
37
|
+
}
|
|
38
|
+
function requiredText(value, path, message) {
|
|
39
|
+
return value?.trim() ? [] : [{ path, message }];
|
|
40
|
+
}
|
|
41
|
+
function acceptedOutcome(body) {
|
|
42
|
+
const outcome = body.outcome;
|
|
43
|
+
if (outcome?.status === "achieved" && !outcome.outcomeRecordId) {
|
|
44
|
+
return [{ path: "/outcome/outcomeRecordId", message: "Achieved outcomes require an accepted outcome record" }];
|
|
45
|
+
}
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
function outcomeRequirements(body, kind) {
|
|
49
|
+
if (!["task", "agent_task", "proposal", "evaluation", "claims", "question"].includes(kind))
|
|
50
|
+
return [];
|
|
51
|
+
return requiredText(body.outcome?.statement?.text, "/outcome/statement/text", `Accepted ${kind} contracts require an outcome`);
|
|
52
|
+
}
|
|
53
|
+
function kindRequirements(body, kind) {
|
|
54
|
+
const issues = [];
|
|
55
|
+
if (kind === "task" && !body.ownerId) {
|
|
56
|
+
issues.push({ path: "/ownerId", message: "Accepted Tasks require an owner" });
|
|
57
|
+
}
|
|
58
|
+
if (kind === "agent_task" && (body.agents?.length ?? 0) === 0) {
|
|
59
|
+
issues.push({ path: "/agents", message: "Accepted Agent Tasks require an agent assignment" });
|
|
60
|
+
}
|
|
61
|
+
if (kind === "proposal" && body.decision === undefined) {
|
|
62
|
+
issues.push({ path: "/decision", message: "Accepted Proposals require an approval model" });
|
|
63
|
+
}
|
|
64
|
+
if (kind === "evaluation" && body.decision === undefined) {
|
|
65
|
+
issues.push({ path: "/decision", message: "Accepted Evaluations require criteria and authority" });
|
|
66
|
+
}
|
|
67
|
+
if (kind === "claims" && (body.attachments?.length ?? 0) === 0) {
|
|
68
|
+
issues.push({ path: "/attachments", message: "Accepted Claims Topics require a deed or claim-collection binding" });
|
|
69
|
+
}
|
|
70
|
+
return issues;
|
|
71
|
+
}
|
|
72
|
+
function lifecycleRequirements(body, kind) {
|
|
73
|
+
if (kind === "discussion" && body.temporalMode !== "ongoing") {
|
|
74
|
+
return requiredText(body.completion?.definition, "/completion/definition", "Finite Discussions require a closure rule");
|
|
75
|
+
}
|
|
76
|
+
if (kind !== "incident")
|
|
77
|
+
return [];
|
|
78
|
+
const issues = requiredText(body.completion?.definition, "/completion/definition", "Accepted Incidents require closure conditions");
|
|
79
|
+
if (!body.ownerId)
|
|
80
|
+
issues.push({ path: "/ownerId", message: "Accepted Incidents require a response owner" });
|
|
81
|
+
return issues;
|
|
82
|
+
}
|
|
83
|
+
export function contractCompleteness(body) {
|
|
84
|
+
if (body.status === "draft" || body.status === "superseded")
|
|
85
|
+
return acceptedOutcome(body);
|
|
86
|
+
const issues = [];
|
|
87
|
+
issues.push(...requiredText(body.intent?.text, "/intent/text", "Accepted contracts require an intent"));
|
|
88
|
+
issues.push(...acceptedOutcome(body));
|
|
89
|
+
const kind = baseTopicKind(body.kindRef);
|
|
90
|
+
if (body.recipe !== topicRecipeForKind(body.kindRef)) {
|
|
91
|
+
issues.push({ path: "/recipe", message: `Recipe must match the ${kind} kind` });
|
|
92
|
+
}
|
|
93
|
+
issues.push(...outcomeRequirements(body, kind));
|
|
94
|
+
issues.push(...kindRequirements(body, kind));
|
|
95
|
+
issues.push(...lifecycleRequirements(body, kind));
|
|
96
|
+
return issues;
|
|
97
|
+
}
|
|
98
|
+
export function assertContractComplete(body) {
|
|
99
|
+
const issues = contractCompleteness(body);
|
|
100
|
+
if (issues.length === 0)
|
|
101
|
+
return;
|
|
102
|
+
throw new TopicProtocolError("CONTRACT_VALIDATION_FAILED", "Topic contract is incomplete for acceptance", { contract: "topic-contract-state", errors: issues });
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=topic-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topic-contract.js","sourceRoot":"","sources":["../../../src/contracts/topic-contract.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
export { CONTRACT_NAMES, type ContractName, } from "./contracts/schemas.js";
|
|
2
2
|
export { assertContract, validateContract, type ContractValidationError, type ContractValidationResult, } from "./contracts/validator.js";
|
|
3
|
+
export { PERSISTED_TOPIC_KINDS, TOPIC_CONTRACT_RECIPES, assertContractComplete, baseTopicKind, contractCompleteness, topicRecipeForKind, type PersistedTopicKind, type TemporalTarget, type TopicAppearance, type TopicAutomationBindingV2, type TopicContractBodyV2, type TopicContractCompletenessIssue, type TopicContractRecipe, type TopicIconName, type TopicKindRef, type TopicRecurrence, type TopicReminder, type TopicRiskV2, type TopicStatementV2, type TopicUserSettings, type Weekday, } from "./contracts/topic-contract.js";
|
|
3
4
|
export { TopicProtocolError, type TopicProtocolErrorCode, } from "./errors.js";
|
|
4
5
|
export { projectTopic } from "./projector/project.js";
|
|
5
|
-
export { selectCanonicalTopicAnchor } from "./matrix/anchors.js";
|
|
6
|
+
export { adoptedTopicAnchor, nativeTopicAnchor, selectCanonicalTopicAnchor } from "./matrix/anchors.js";
|
|
6
7
|
export { assertMatrixAnchor, assertMatrixRoomId, assertServerEventId, assertTopicMessageContent, buildTopicMessageContent, buildTopicOperationContent, buildTopicRootContent, createTopicId, createTopicOperationId, } from "./matrix/content.js";
|
|
7
8
|
export { TOPIC_RECORD_KEY, TOPIC_RECORD_MSGTYPE, TOPIC_SOURCE_KEY, TOPIC_SOURCE_KINDS, TOPIC_SOURCE_MSGTYPE, createTopicRecordMessageContent, createTopicSourceMessageContent, parseTopicRecordMessageContent, parseTopicSourceMessageContent, type CreateTopicRecordMessageInput, type CreateTopicSourceMessageInput, type TopicCardContext, type TopicRecordMessageContent, type TopicSourceDisclosure, type TopicSourceKind, type TopicSourceMessageContent, type TopicSourceReference, } from "./matrix/cards.js";
|
|
8
9
|
export { isTopicInfrastructureEvent, parseTopicRootEvent, projectMatrixTopic, } from "./matrix/events.js";
|
|
9
10
|
export { JsonPendingTopicStore, MemoryPendingTopicStore, type TopicKeyValueStore, } from "./matrix/pending.js";
|
|
10
11
|
export { TopicRuntime, type TopicRuntimeOptions } from "./matrix/runtime.js";
|
|
11
12
|
export { MATRIX_ROOM_MESSAGE, TOPIC_ANCHOR_KEY, TOPIC_METADATA_KEY, TOPIC_OPERATION_EVENT_TYPE, type CanonicalTopicAnchor, type MatrixEventContent, type MatrixSendRequest, type MatrixTopicProjection, type MatrixTopicProjectionInput, type ParsedTopicRoot, type PendingTopicCreation, type PendingTopicStore, type RejectedTopicEvent, type RejectedTopicEventReason, type TopicAnchorConflict, type TopicCreationInput, type TopicCreationResult, type TopicFirstMessageFactory, type TopicMatrixEvent, type TopicMatrixTransport, type TopicRootContentOptions, } from "./matrix/types.js";
|
|
12
|
-
export { TOPIC_KINDS, TOPIC_CONTEXT_TYPES, TOPIC_STATUSES, TOPIC_VFS_FILE_PROVIDER, type IgnoredOperation, type IgnoredOperationReason, type MatrixAnchor, type ProjectedTopicRelation, type ProjectionInput, type TopicContext, type TopicContextType, type TopicFileAttachmentIdentity, type TopicDecision, type TopicKind, type TopicNextStep, type TopicOperation, type TopicOperationType, type TopicProjection, type ProjectedTopicAttachment, type ProjectedTopicOverview, type TopicOverview, type TopicProjectionConflict, type TopicRelationType, type TopicRoot, type TopicStatus, type TopicVfsFileReference, isCanonicalTopicContextType, } from "./projector/types.js";
|
|
13
|
+
export { TOPIC_KINDS, TOPIC_CONTEXT_TYPES, TOPIC_STATUSES, TOPIC_VFS_FILE_PROVIDER, type IgnoredOperation, type IgnoredOperationReason, type MatrixAnchor, type TopicAnchor, type ProjectedTopicRelation, type ProjectionInput, type TopicContext, type TopicContextType, type TopicFileAttachmentIdentity, type TopicDecision, type EffectiveTopicContractReference, type TopicAutomationBinding, type TopicAutomationStatus, type TopicContractHeads, type TopicContractReference, type TopicKind, type TopicNextStep, type TopicOperation, type TopicOperationType, type TopicProjection, type ProjectedTopicAttachment, type ProjectedTopicOverview, type TopicOverview, type TopicProjectionConflict, type TopicRelationType, type TopicRoot, type TopicRootV2, type LegacyTopicRoot, type TopicStatus, type TopicVfsFileReference, isCanonicalTopicContextType, } from "./projector/types.js";
|
|
13
14
|
export { TOPIC_RECORD_KINDS, type TopicRecord, type TopicRecordKind, } from "./records/types.js";
|
|
15
|
+
export { emptyTopicIndexSnapshot, reconcileTopicIndex } from "./indexing/reconcile.js";
|
|
16
|
+
export { searchTopicIndex } from "./indexing/search.js";
|
|
17
|
+
export { rankTopicIndex } from "./indexing/rank.js";
|
|
18
|
+
export { TOPIC_INDEX_COMPLETENESS, TOPIC_INDEX_RANK_REASONS, TOPIC_INDEX_STORAGE_STATES, TOPIC_INDEX_UNREAD_STATES, TOPIC_NOTIFICATION_MODES, type RankedTopicIndexEntry, type TopicAttentionSignalMap, type TopicAttentionSignals, type TopicIndexCompleteness, type TopicIndexDomain, type TopicIndexEntry, type TopicIndexObservation, type TopicIndexRankReason, type TopicIndexReconciliation, type TopicIndexSearchFilters, type TopicIndexSnapshot, type TopicIndexStorageState, type TopicIndexTombstone, type TopicIndexUnreadState, type TopicNotificationMode, type TopicPreference, type TopicPreferenceMap, } from "./indexing/types.js";
|
package/dist/src/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { CONTRACT_NAMES, } from "./contracts/schemas.js";
|
|
2
2
|
export { assertContract, validateContract, } from "./contracts/validator.js";
|
|
3
|
+
export { PERSISTED_TOPIC_KINDS, TOPIC_CONTRACT_RECIPES, assertContractComplete, baseTopicKind, contractCompleteness, topicRecipeForKind, } from "./contracts/topic-contract.js";
|
|
3
4
|
export { TopicProtocolError, } from "./errors.js";
|
|
4
5
|
export { projectTopic } from "./projector/project.js";
|
|
5
|
-
export { selectCanonicalTopicAnchor } from "./matrix/anchors.js";
|
|
6
|
+
export { adoptedTopicAnchor, nativeTopicAnchor, selectCanonicalTopicAnchor } from "./matrix/anchors.js";
|
|
6
7
|
export { assertMatrixAnchor, assertMatrixRoomId, assertServerEventId, assertTopicMessageContent, buildTopicMessageContent, buildTopicOperationContent, buildTopicRootContent, createTopicId, createTopicOperationId, } from "./matrix/content.js";
|
|
7
8
|
export { TOPIC_RECORD_KEY, TOPIC_RECORD_MSGTYPE, TOPIC_SOURCE_KEY, TOPIC_SOURCE_KINDS, TOPIC_SOURCE_MSGTYPE, createTopicRecordMessageContent, createTopicSourceMessageContent, parseTopicRecordMessageContent, parseTopicSourceMessageContent, } from "./matrix/cards.js";
|
|
8
9
|
export { isTopicInfrastructureEvent, parseTopicRootEvent, projectMatrixTopic, } from "./matrix/events.js";
|
|
@@ -11,4 +12,8 @@ export { TopicRuntime } from "./matrix/runtime.js";
|
|
|
11
12
|
export { MATRIX_ROOM_MESSAGE, TOPIC_ANCHOR_KEY, TOPIC_METADATA_KEY, TOPIC_OPERATION_EVENT_TYPE, } from "./matrix/types.js";
|
|
12
13
|
export { TOPIC_KINDS, TOPIC_CONTEXT_TYPES, TOPIC_STATUSES, TOPIC_VFS_FILE_PROVIDER, isCanonicalTopicContextType, } from "./projector/types.js";
|
|
13
14
|
export { TOPIC_RECORD_KINDS, } from "./records/types.js";
|
|
15
|
+
export { emptyTopicIndexSnapshot, reconcileTopicIndex } from "./indexing/reconcile.js";
|
|
16
|
+
export { searchTopicIndex } from "./indexing/search.js";
|
|
17
|
+
export { rankTopicIndex } from "./indexing/rank.js";
|
|
18
|
+
export { TOPIC_INDEX_COMPLETENESS, TOPIC_INDEX_RANK_REASONS, TOPIC_INDEX_STORAGE_STATES, TOPIC_INDEX_UNREAD_STATES, TOPIC_NOTIFICATION_MODES, } from "./indexing/types.js";
|
|
14
19
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,gBAAgB,GAGjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,kBAAkB,GAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,gBAAgB,GAGjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,kBAAkB,GAgBnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,GAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACxG,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC1B,qBAAqB,EACrB,aAAa,EACb,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,+BAA+B,EAC/B,+BAA+B,EAC/B,8BAA8B,EAC9B,8BAA8B,GAS/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAExB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAA4B,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,GAkB3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EA+BvB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,GAkBzB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { RankedTopicIndexEntry, TopicAttentionSignalMap, TopicIndexEntry, TopicPreferenceMap } from "./types.js";
|
|
2
|
+
export declare function rankTopicIndex(entries: readonly TopicIndexEntry[], preferences?: TopicPreferenceMap, signals?: TopicAttentionSignalMap): RankedTopicIndexEntry[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { compareText } from "../shared/compare.js";
|
|
2
|
+
const REASON_RANK = {
|
|
3
|
+
pinned: 0,
|
|
4
|
+
"direct-attention": 1,
|
|
5
|
+
"followed-unread": 2,
|
|
6
|
+
participated: 3,
|
|
7
|
+
recent: 4,
|
|
8
|
+
};
|
|
9
|
+
function reasonFor(entry, preferences, signals) {
|
|
10
|
+
const preference = preferences[entry.topicId];
|
|
11
|
+
if (preference?.pinned)
|
|
12
|
+
return "pinned";
|
|
13
|
+
if (signals[entry.topicId]?.directAttention)
|
|
14
|
+
return "direct-attention";
|
|
15
|
+
if (preference?.notificationMode === "follow" && entry.unread === "unread")
|
|
16
|
+
return "followed-unread";
|
|
17
|
+
if (entry.participated)
|
|
18
|
+
return "participated";
|
|
19
|
+
return "recent";
|
|
20
|
+
}
|
|
21
|
+
function compareRanked(left, right) {
|
|
22
|
+
return REASON_RANK[left.reason] - REASON_RANK[right.reason]
|
|
23
|
+
|| compareText(right.entry.latestActivityAt, left.entry.latestActivityAt)
|
|
24
|
+
|| compareText(left.entry.topicId, right.entry.topicId);
|
|
25
|
+
}
|
|
26
|
+
export function rankTopicIndex(entries, preferences = {}, signals = {}) {
|
|
27
|
+
return entries
|
|
28
|
+
.map((entry) => ({ entry, reason: reasonFor(entry, preferences, signals) }))
|
|
29
|
+
.sort(compareRanked);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=rank.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rank.js","sourceRoot":"","sources":["../../../src/indexing/rank.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AASnD,MAAM,WAAW,GAAyC;IACxD,MAAM,EAAE,CAAC;IACT,kBAAkB,EAAE,CAAC;IACrB,iBAAiB,EAAE,CAAC;IACpB,YAAY,EAAE,CAAC;IACf,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,SAAS,SAAS,CAAC,KAAsB,EAAE,WAA+B,EAAE,OAAgC;IAC1G,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,UAAU,EAAE,MAAM;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,eAAe;QAAE,OAAO,kBAAkB,CAAC;IACvE,IAAI,UAAU,EAAE,gBAAgB,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,iBAAiB,CAAC;IACrG,IAAI,KAAK,CAAC,YAAY;QAAE,OAAO,cAAc,CAAC;IAC9C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,IAA2B,EAAE,KAA4B;IAC9E,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;WACtD,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC;WACtE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAmC,EACnC,cAAkC,EAAE,EACpC,UAAmC,EAAE;IAErC,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;SAC3E,IAAI,CAAC,aAAa,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { TopicIndexReconciliation, TopicIndexSnapshot } from "./types.js";
|
|
2
|
+
export declare function emptyTopicIndexSnapshot(updatedAt: string): TopicIndexSnapshot;
|
|
3
|
+
export declare function reconcileTopicIndex(snapshot: TopicIndexSnapshot, input: TopicIndexReconciliation): TopicIndexSnapshot;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { compareText } from "../shared/compare.js";
|
|
2
|
+
const COMPLETENESS_RANK = {
|
|
3
|
+
complete: 4,
|
|
4
|
+
"partial-history": 3,
|
|
5
|
+
"metadata-pending": 2,
|
|
6
|
+
"decryption-pending": 1,
|
|
7
|
+
};
|
|
8
|
+
function compareEntries(left, right) {
|
|
9
|
+
return compareText(left.indexedAt, right.indexedAt)
|
|
10
|
+
|| COMPLETENESS_RANK[left.completeness] - COMPLETENESS_RANK[right.completeness]
|
|
11
|
+
|| compareText(right.roomId, left.roomId)
|
|
12
|
+
|| compareText(right.rootEventId, left.rootEventId);
|
|
13
|
+
}
|
|
14
|
+
function latestEntries(entries) {
|
|
15
|
+
const byTopic = new Map();
|
|
16
|
+
entries.forEach((entry) => {
|
|
17
|
+
const current = byTopic.get(entry.topicId);
|
|
18
|
+
if (current === undefined || compareEntries(current, entry) < 0)
|
|
19
|
+
byTopic.set(entry.topicId, entry);
|
|
20
|
+
});
|
|
21
|
+
return byTopic;
|
|
22
|
+
}
|
|
23
|
+
function latestTombstones(tombstones) {
|
|
24
|
+
const byRoom = new Map();
|
|
25
|
+
tombstones.forEach((tombstone) => {
|
|
26
|
+
const current = byRoom.get(tombstone.roomId);
|
|
27
|
+
if (current === undefined || compareText(current.removedAt, tombstone.removedAt) < 0)
|
|
28
|
+
byRoom.set(tombstone.roomId, tombstone);
|
|
29
|
+
});
|
|
30
|
+
return byRoom;
|
|
31
|
+
}
|
|
32
|
+
function isAfterTombstone(entry, tombstones) {
|
|
33
|
+
const tombstone = tombstones.get(entry.roomId);
|
|
34
|
+
return tombstone === undefined || compareText(tombstone.removedAt, entry.indexedAt) < 0;
|
|
35
|
+
}
|
|
36
|
+
export function emptyTopicIndexSnapshot(updatedAt) {
|
|
37
|
+
return { version: 1, updatedAt, entries: [], tombstones: [] };
|
|
38
|
+
}
|
|
39
|
+
export function reconcileTopicIndex(snapshot, input) {
|
|
40
|
+
const removed = new Set(input.leftRoomIds ?? []);
|
|
41
|
+
const tombstones = latestTombstones([
|
|
42
|
+
...snapshot.tombstones,
|
|
43
|
+
...[...removed].map((roomId) => ({ roomId, removedAt: input.reconciledAt })),
|
|
44
|
+
]);
|
|
45
|
+
const observed = input.observations
|
|
46
|
+
.filter(({ canonicalAnchor }) => canonicalAnchor)
|
|
47
|
+
.map(({ entry }) => entry);
|
|
48
|
+
const entries = [...latestEntries([...snapshot.entries, ...observed]).values()]
|
|
49
|
+
.filter((entry) => !removed.has(entry.roomId) && isAfterTombstone(entry, tombstones))
|
|
50
|
+
.sort((left, right) => compareText(left.topicId, right.topicId));
|
|
51
|
+
return {
|
|
52
|
+
version: 1,
|
|
53
|
+
updatedAt: input.reconciledAt,
|
|
54
|
+
entries,
|
|
55
|
+
tombstones: [...tombstones.values()].sort((left, right) => compareText(left.roomId, right.roomId)),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../../src/indexing/reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { compareText } from "../shared/compare.js";
|
|
2
|
+
function includesAny(value, accepted) {
|
|
3
|
+
return accepted === undefined || accepted.length === 0 || (value !== undefined && accepted.includes(value));
|
|
4
|
+
}
|
|
5
|
+
function includesSource(entry, accepted) {
|
|
6
|
+
return accepted === undefined || accepted.length === 0 || accepted.some((kind) => entry.sourceKinds?.includes(kind));
|
|
7
|
+
}
|
|
8
|
+
function searchText(entry) {
|
|
9
|
+
return [
|
|
10
|
+
entry.title,
|
|
11
|
+
entry.currentState,
|
|
12
|
+
entry.domain?.name,
|
|
13
|
+
entry.domain?.id,
|
|
14
|
+
...(entry.context?.flatMap(({ type, id }) => [type, id]) ?? []),
|
|
15
|
+
].filter((value) => value !== undefined).join(" ").toLowerCase();
|
|
16
|
+
}
|
|
17
|
+
function matchesQuery(entry, query) {
|
|
18
|
+
const tokens = query?.trim().toLowerCase().split(/\s+/).filter(Boolean) ?? [];
|
|
19
|
+
if (tokens.length === 0)
|
|
20
|
+
return true;
|
|
21
|
+
const haystack = searchText(entry);
|
|
22
|
+
return tokens.every((token) => haystack.includes(token));
|
|
23
|
+
}
|
|
24
|
+
function matchesFollowing(entry, following, preferences) {
|
|
25
|
+
if (following === undefined)
|
|
26
|
+
return true;
|
|
27
|
+
return (preferences[entry.topicId]?.notificationMode === "follow") === following;
|
|
28
|
+
}
|
|
29
|
+
export function searchTopicIndex(entries, filters = {}, preferences = {}) {
|
|
30
|
+
return entries.filter((entry) => matchesQuery(entry, filters.query)
|
|
31
|
+
&& includesAny(entry.status, filters.statuses)
|
|
32
|
+
&& includesAny(entry.domain?.id, filters.domainIds)
|
|
33
|
+
&& includesAny(entry.kind, filters.kinds)
|
|
34
|
+
&& includesSource(entry, filters.sourceKinds)
|
|
35
|
+
&& matchesFollowing(entry, filters.following, preferences)).sort((left, right) => compareText(left.title ?? "", right.title ?? "") || compareText(left.topicId, right.topicId));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/indexing/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { TopicSourceKind } from "../matrix/cards.js";
|
|
2
|
+
import type { TopicContext, TopicKind, TopicStatus } from "../projector/types.js";
|
|
3
|
+
import type { TopicUserSettings } from "../contracts/topic-contract.js";
|
|
4
|
+
export declare const TOPIC_INDEX_COMPLETENESS: readonly ["complete", "partial-history", "metadata-pending", "decryption-pending"];
|
|
5
|
+
export declare const TOPIC_INDEX_UNREAD_STATES: readonly ["unread", "read", "unknown"];
|
|
6
|
+
export declare const TOPIC_INDEX_STORAGE_STATES: readonly ["encrypted", "memory-only", "locked", "unavailable"];
|
|
7
|
+
export declare const TOPIC_NOTIFICATION_MODES: readonly ["follow", "default", "mute"];
|
|
8
|
+
export declare const TOPIC_INDEX_RANK_REASONS: readonly ["pinned", "direct-attention", "followed-unread", "participated", "recent"];
|
|
9
|
+
export type TopicIndexCompleteness = (typeof TOPIC_INDEX_COMPLETENESS)[number];
|
|
10
|
+
export type TopicIndexUnreadState = (typeof TOPIC_INDEX_UNREAD_STATES)[number];
|
|
11
|
+
export type TopicIndexStorageState = (typeof TOPIC_INDEX_STORAGE_STATES)[number];
|
|
12
|
+
export type TopicNotificationMode = (typeof TOPIC_NOTIFICATION_MODES)[number];
|
|
13
|
+
export type TopicIndexRankReason = (typeof TOPIC_INDEX_RANK_REASONS)[number];
|
|
14
|
+
export interface TopicIndexDomain {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly name?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TopicIndexEntry {
|
|
19
|
+
readonly topicId: string;
|
|
20
|
+
readonly roomId: string;
|
|
21
|
+
readonly rootEventId: string;
|
|
22
|
+
readonly title?: string;
|
|
23
|
+
readonly currentState?: string;
|
|
24
|
+
readonly status: TopicStatus;
|
|
25
|
+
readonly kind?: TopicKind;
|
|
26
|
+
readonly domain?: TopicIndexDomain;
|
|
27
|
+
readonly context?: readonly TopicContext[];
|
|
28
|
+
readonly sourceKinds?: readonly TopicSourceKind[];
|
|
29
|
+
readonly latestActivityAt: string;
|
|
30
|
+
readonly latestEventId?: string;
|
|
31
|
+
readonly participated: boolean;
|
|
32
|
+
readonly unread: TopicIndexUnreadState;
|
|
33
|
+
readonly completeness: TopicIndexCompleteness;
|
|
34
|
+
readonly indexedAt: string;
|
|
35
|
+
}
|
|
36
|
+
export interface TopicIndexTombstone {
|
|
37
|
+
readonly roomId: string;
|
|
38
|
+
readonly removedAt: string;
|
|
39
|
+
}
|
|
40
|
+
export interface TopicIndexSnapshot {
|
|
41
|
+
readonly version: 1;
|
|
42
|
+
readonly updatedAt: string;
|
|
43
|
+
readonly entries: readonly TopicIndexEntry[];
|
|
44
|
+
readonly tombstones: readonly TopicIndexTombstone[];
|
|
45
|
+
}
|
|
46
|
+
export interface TopicPreference extends TopicUserSettings {
|
|
47
|
+
readonly notificationMode: TopicNotificationMode;
|
|
48
|
+
readonly pinned: boolean;
|
|
49
|
+
readonly markedUnreadFrom?: string | null;
|
|
50
|
+
}
|
|
51
|
+
export type TopicPreferenceMap = Readonly<Record<string, TopicPreference>>;
|
|
52
|
+
export interface TopicIndexObservation {
|
|
53
|
+
readonly entry: TopicIndexEntry;
|
|
54
|
+
readonly canonicalAnchor: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface TopicIndexReconciliation {
|
|
57
|
+
readonly observations: readonly TopicIndexObservation[];
|
|
58
|
+
readonly leftRoomIds?: readonly string[];
|
|
59
|
+
readonly reconciledAt: string;
|
|
60
|
+
}
|
|
61
|
+
export interface TopicIndexSearchFilters {
|
|
62
|
+
readonly query?: string;
|
|
63
|
+
readonly statuses?: readonly TopicStatus[];
|
|
64
|
+
readonly domainIds?: readonly string[];
|
|
65
|
+
readonly following?: boolean;
|
|
66
|
+
readonly kinds?: readonly TopicKind[];
|
|
67
|
+
readonly sourceKinds?: readonly TopicSourceKind[];
|
|
68
|
+
}
|
|
69
|
+
export interface TopicAttentionSignals {
|
|
70
|
+
readonly directAttention?: boolean;
|
|
71
|
+
}
|
|
72
|
+
export type TopicAttentionSignalMap = Readonly<Record<string, TopicAttentionSignals>>;
|
|
73
|
+
export interface RankedTopicIndexEntry {
|
|
74
|
+
readonly entry: TopicIndexEntry;
|
|
75
|
+
readonly reason: TopicIndexRankReason;
|
|
76
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const TOPIC_INDEX_COMPLETENESS = [
|
|
2
|
+
"complete",
|
|
3
|
+
"partial-history",
|
|
4
|
+
"metadata-pending",
|
|
5
|
+
"decryption-pending",
|
|
6
|
+
];
|
|
7
|
+
export const TOPIC_INDEX_UNREAD_STATES = ["unread", "read", "unknown"];
|
|
8
|
+
export const TOPIC_INDEX_STORAGE_STATES = [
|
|
9
|
+
"encrypted",
|
|
10
|
+
"memory-only",
|
|
11
|
+
"locked",
|
|
12
|
+
"unavailable",
|
|
13
|
+
];
|
|
14
|
+
export const TOPIC_NOTIFICATION_MODES = ["follow", "default", "mute"];
|
|
15
|
+
export const TOPIC_INDEX_RANK_REASONS = [
|
|
16
|
+
"pinned",
|
|
17
|
+
"direct-attention",
|
|
18
|
+
"followed-unread",
|
|
19
|
+
"participated",
|
|
20
|
+
"recent",
|
|
21
|
+
];
|
|
22
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/indexing/types.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,UAAU;IACV,iBAAiB;IACjB,kBAAkB;IAClB,oBAAoB;CACZ,CAAC;AACX,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAU,CAAC;AAChF,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,WAAW;IACX,aAAa;IACb,QAAQ;IACR,aAAa;CACL,CAAC;AACX,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAU,CAAC;AAC/E,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,QAAQ;IACR,kBAAkB;IAClB,iBAAiB;IACjB,cAAc;IACd,QAAQ;CACA,CAAC"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
+
import type { MatrixAnchor, TopicAnchor } from "../projector/types.js";
|
|
1
2
|
import type { CanonicalTopicAnchor, TopicMatrixEvent } from "./types.js";
|
|
3
|
+
export declare function nativeTopicAnchor(anchor: MatrixAnchor): TopicAnchor;
|
|
4
|
+
export declare function adoptedTopicAnchor(anchor: MatrixAnchor): TopicAnchor;
|
|
2
5
|
export declare function selectCanonicalTopicAnchor(events: readonly TopicMatrixEvent[], topicId: string): CanonicalTopicAnchor;
|