@ue-shed/game-text 0.1.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.
@@ -0,0 +1,220 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { TextCorpus, TextCorpusDiagnostic, TextLocation, TextOccurrenceId, TextUnitId } from "./schema.js";
3
+ const SafeIdentifier = Schema.Trim.check(Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/));
4
+ const EvidenceValue = Schema.Trim.check(Schema.isNonEmpty(), Schema.isMaxLength(1024));
5
+ const AuthoredGuidance = Schema.Trim.check(Schema.isNonEmpty(), Schema.isMaxLength(2048));
6
+ const PositiveInt = Schema.Int.check(Schema.isGreaterThan(0));
7
+ const EvidenceOperator = Schema.Literals(["exact", "prefix"]);
8
+ export const TextRoleId = SafeIdentifier.pipe(Schema.brand("TextRoleId"));
9
+ export const TextQualityRuleId = SafeIdentifier.pipe(Schema.brand("TextQualityRuleId"));
10
+ export const TextRoleMatcher = Schema.Union([
11
+ Schema.Struct({
12
+ kind: Schema.Literal("location_kind"),
13
+ value: Schema.Literals(["data_table_cell", "string_table_entry", "asset_property"])
14
+ }),
15
+ Schema.Struct({
16
+ kind: Schema.Literal("object_path"),
17
+ operator: EvidenceOperator,
18
+ value: EvidenceValue
19
+ }),
20
+ Schema.Struct({
21
+ kind: Schema.Literal("row"),
22
+ operator: EvidenceOperator,
23
+ value: EvidenceValue
24
+ }),
25
+ Schema.Struct({
26
+ kind: Schema.Literal("property_path"),
27
+ operator: EvidenceOperator,
28
+ value: EvidenceValue
29
+ }),
30
+ Schema.Struct({
31
+ kind: Schema.Literal("string_table_entry"),
32
+ operator: EvidenceOperator,
33
+ value: EvidenceValue
34
+ }),
35
+ Schema.Struct({
36
+ kind: Schema.Literal("class_path"),
37
+ operator: EvidenceOperator,
38
+ value: EvidenceValue
39
+ })
40
+ ]);
41
+ export const TextRoleScope = Schema.Struct({
42
+ matchers: Schema.Array(TextRoleMatcher).check(Schema.isMinLength(1), Schema.isMaxLength(16))
43
+ });
44
+ export const TextRole = Schema.Struct({
45
+ id: TextRoleId,
46
+ description: Schema.optionalKey(AuthoredGuidance),
47
+ scopes: Schema.Array(TextRoleScope).check(Schema.isMinLength(1), Schema.isMaxLength(64))
48
+ });
49
+ export const TextTerminologyEntry = Schema.Union([
50
+ Schema.Struct({ kind: Schema.Literal("forbidden"), term: EvidenceValue }),
51
+ Schema.Struct({
52
+ kind: Schema.Literal("preferred"),
53
+ alternatives: Schema.Array(EvidenceValue).check(Schema.isMinLength(1), Schema.isMaxLength(64)),
54
+ term: EvidenceValue
55
+ })
56
+ ]);
57
+ export const TextQualityRule = Schema.Union([
58
+ Schema.Struct({
59
+ kind: Schema.Literal("character_budget"),
60
+ id: TextQualityRuleId,
61
+ maximumCharacters: PositiveInt,
62
+ recovery: AuthoredGuidance,
63
+ role: TextRoleId
64
+ }),
65
+ Schema.Struct({
66
+ kind: Schema.Literal("terminology"),
67
+ caseSensitive: Schema.Boolean,
68
+ id: TextQualityRuleId,
69
+ recovery: AuthoredGuidance,
70
+ role: TextRoleId,
71
+ terms: Schema.Array(TextTerminologyEntry).check(Schema.isMinLength(1), Schema.isMaxLength(256))
72
+ })
73
+ ]);
74
+ export const TextQualityRuleDocument = Schema.Struct({
75
+ rules: Schema.Array(TextQualityRule).check(Schema.isMinLength(1), Schema.isMaxLength(512)),
76
+ roles: Schema.Array(TextRole).check(Schema.isMinLength(1), Schema.isMaxLength(256)),
77
+ schemaVersion: Schema.Literal(1)
78
+ });
79
+ export class TextQualityRuleDocumentError extends Schema.TaggedErrorClass()("TextQualityRuleDocumentError", {
80
+ code: Schema.Literals([
81
+ "invalid_json",
82
+ "invalid_structure",
83
+ "duplicate_role_id",
84
+ "duplicate_rule_id",
85
+ "unknown_role_id"
86
+ ]),
87
+ message: Schema.String,
88
+ recovery: Schema.String
89
+ }) {
90
+ }
91
+ function ruleDocumentError(code) {
92
+ switch (code) {
93
+ case "invalid_json":
94
+ return new TextQualityRuleDocumentError({
95
+ code,
96
+ message: "The Game Text quality rule file is not valid JSON.",
97
+ recovery: "Correct the JSON syntax and retry with a version-1 rule document."
98
+ });
99
+ case "invalid_structure":
100
+ return new TextQualityRuleDocumentError({
101
+ code,
102
+ message: "The Game Text quality rule document does not match the version-1 schema.",
103
+ recovery: "Provide schemaVersion 1 with non-empty roles, scopes, matchers, rules, and authored recovery guidance."
104
+ });
105
+ case "duplicate_role_id":
106
+ return new TextQualityRuleDocumentError({
107
+ code,
108
+ message: "The Game Text quality rule document contains a duplicate role ID.",
109
+ recovery: "Give every role a unique stable ID and retry."
110
+ });
111
+ case "duplicate_rule_id":
112
+ return new TextQualityRuleDocumentError({
113
+ code,
114
+ message: "The Game Text quality rule document contains a duplicate rule ID.",
115
+ recovery: "Give every rule a unique stable ID and retry."
116
+ });
117
+ case "unknown_role_id":
118
+ return new TextQualityRuleDocumentError({
119
+ code,
120
+ message: "A Game Text quality rule references a role that is not declared.",
121
+ recovery: "Declare the referenced role or update the rule to use an existing role ID."
122
+ });
123
+ }
124
+ }
125
+ function firstDuplicate(values) {
126
+ return new Set(values).size !== values.length;
127
+ }
128
+ function validateRuleDocument(document) {
129
+ if (firstDuplicate(document.roles.map((role) => role.id))) {
130
+ return Effect.fail(ruleDocumentError("duplicate_role_id"));
131
+ }
132
+ if (firstDuplicate(document.rules.map((rule) => rule.id))) {
133
+ return Effect.fail(ruleDocumentError("duplicate_rule_id"));
134
+ }
135
+ const roles = new Set(document.roles.map((role) => role.id));
136
+ if (document.rules.some((rule) => !roles.has(rule.role))) {
137
+ return Effect.fail(ruleDocumentError("unknown_role_id"));
138
+ }
139
+ return Effect.succeed(document);
140
+ }
141
+ export function decodeTextQualityRuleDocument(input) {
142
+ return Schema.decodeUnknownEffect(TextQualityRuleDocument)(input).pipe(Effect.mapError(() => ruleDocumentError("invalid_structure")), Effect.flatMap(validateRuleDocument));
143
+ }
144
+ export function decodeTextQualityRuleDocumentJson(input) {
145
+ return Effect.try({
146
+ try: () => JSON.parse(input),
147
+ catch: () => ruleDocumentError("invalid_json")
148
+ }).pipe(Effect.flatMap(decodeTextQualityRuleDocument));
149
+ }
150
+ export const TextQualityAffectedOccurrence = Schema.Struct({
151
+ id: TextOccurrenceId,
152
+ location: TextLocation,
153
+ packageFile: Schema.String
154
+ });
155
+ export const CharacterBudgetActual = Schema.Struct({
156
+ characterCount: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
157
+ kind: Schema.Literal("character_count"),
158
+ source: Schema.String
159
+ });
160
+ export const CharacterBudgetExpectation = Schema.Struct({
161
+ kind: Schema.Literal("maximum_characters"),
162
+ maximumCharacters: PositiveInt
163
+ });
164
+ export const TerminologyActual = Schema.Struct({
165
+ end: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
166
+ kind: Schema.Literal("terminology_match"),
167
+ source: Schema.String,
168
+ start: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
169
+ term: EvidenceValue
170
+ });
171
+ export const TerminologyExpectation = Schema.Union([
172
+ Schema.Struct({ kind: Schema.Literal("forbidden_term"), term: EvidenceValue }),
173
+ Schema.Struct({
174
+ discouragedTerm: EvidenceValue,
175
+ kind: Schema.Literal("preferred_term"),
176
+ preferredTerm: EvidenceValue
177
+ })
178
+ ]);
179
+ const FindingBase = {
180
+ affectedOccurrences: Schema.Array(TextQualityAffectedOccurrence).check(Schema.isMinLength(1)),
181
+ recovery: AuthoredGuidance,
182
+ role: TextRoleId,
183
+ ruleId: TextQualityRuleId,
184
+ textUnitId: TextUnitId
185
+ };
186
+ export const TextQualityFinding = Schema.Union([
187
+ Schema.Struct({
188
+ ...FindingBase,
189
+ actual: CharacterBudgetActual,
190
+ expectation: CharacterBudgetExpectation,
191
+ kind: Schema.Literal("character_budget")
192
+ }),
193
+ Schema.Struct({
194
+ ...FindingBase,
195
+ actual: TerminologyActual,
196
+ expectation: TerminologyExpectation,
197
+ kind: Schema.Literal("terminology")
198
+ })
199
+ ]);
200
+ export const TextQualityRoleSummary = Schema.Struct({
201
+ matchedOccurrences: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
202
+ matchedTextUnits: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
203
+ role: TextRoleId
204
+ });
205
+ export const TextQualityRuleSummary = Schema.Struct({
206
+ findingCount: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
207
+ ruleId: TextQualityRuleId
208
+ });
209
+ export const TextQualityReport = Schema.Struct({
210
+ coverage: TextCorpus.fields.coverage,
211
+ diagnostics: Schema.Array(TextCorpusDiagnostic),
212
+ findings: Schema.Array(TextQualityFinding),
213
+ roles: Schema.Array(TextQualityRoleSummary),
214
+ ruleDocumentVersion: TextQualityRuleDocument.fields.schemaVersion,
215
+ rules: Schema.Array(TextQualityRuleSummary),
216
+ schemaVersion: Schema.Literal(1),
217
+ status: TextCorpus.fields.status
218
+ });
219
+ export const decodeTextQualityReport = Schema.decodeUnknownEffect(TextQualityReport);
220
+ //# sourceMappingURL=quality-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-schema.js","sourceRoot":"","sources":["../src/quality-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { TextCorpus, TextLocation, TextOccurrence } from "./schema.js";
2
+ import type { TextQualityReport, TextQualityRuleDocument, TextRole, TextRoleMatcher } from "./quality-schema.js";
3
+ export declare function matchesTextRoleMatcher(location: TextLocation, matcher: TextRoleMatcher): boolean;
4
+ export declare function matchesTextRole(occurrence: TextOccurrence, role: TextRole): boolean;
5
+ /** Pure quality evaluation over an already-built TextCorpus. */
6
+ export declare function evaluateTextQuality(corpus: TextCorpus, document: TextQualityRuleDocument): TextQualityReport;
7
+ //# sourceMappingURL=quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../src/quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAY,MAAM,aAAa,CAAC;AACtF,OAAO,KAAK,EAGX,iBAAiB,EAEjB,uBAAuB,EACvB,QAAQ,EACR,eAAe,EACf,MAAM,qBAAqB,CAAC;AAM7B,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CA2BhG;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAInF;AAgID,gEAAgE;AAChE,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,uBAAuB,GAC/B,iBAAiB,CAuCnB"}
@@ -0,0 +1,150 @@
1
+ function matchesValue(actual, expected, operator) {
2
+ return operator === "exact" ? actual === expected : actual.startsWith(expected);
3
+ }
4
+ export function matchesTextRoleMatcher(location, matcher) {
5
+ switch (matcher.kind) {
6
+ case "location_kind":
7
+ return location.kind === matcher.value;
8
+ case "object_path":
9
+ return matchesValue(location.objectPath, matcher.value, matcher.operator);
10
+ case "row":
11
+ return (location.kind === "data_table_cell" &&
12
+ matchesValue(location.row, matcher.value, matcher.operator));
13
+ case "property_path":
14
+ return (location.kind !== "string_table_entry" &&
15
+ matchesValue(location.propertyPath, matcher.value, matcher.operator));
16
+ case "string_table_entry":
17
+ return (location.kind === "string_table_entry" &&
18
+ matchesValue(location.entryKey, matcher.value, matcher.operator));
19
+ case "class_path":
20
+ return (location.kind === "asset_property" &&
21
+ matchesValue(location.classPath, matcher.value, matcher.operator));
22
+ }
23
+ }
24
+ export function matchesTextRole(occurrence, role) {
25
+ return role.scopes.some((scope) => scope.matchers.every((matcher) => matchesTextRoleMatcher(occurrence.location, matcher)));
26
+ }
27
+ function affectedOccurrence(occurrence) {
28
+ return {
29
+ id: occurrence.id,
30
+ location: occurrence.location,
31
+ packageFile: occurrence.packageFile
32
+ };
33
+ }
34
+ function occurrenceGroups(unit, role) {
35
+ const groups = new Map();
36
+ for (const occurrence of unit.occurrences) {
37
+ if (!matchesTextRole(occurrence, role))
38
+ continue;
39
+ groups.set(occurrence.source, [...(groups.get(occurrence.source) ?? []), occurrence]);
40
+ }
41
+ return [...groups]
42
+ .sort(([left], [right]) => left.localeCompare(right))
43
+ .map(([source, occurrences]) => ({
44
+ occurrences: [...occurrences].sort((left, right) => left.id.localeCompare(right.id)),
45
+ source
46
+ }));
47
+ }
48
+ function characterBudgetFindings(options) {
49
+ return occurrenceGroups(options.unit, options.role).flatMap(({ occurrences, source }) => source.length > options.rule.maximumCharacters
50
+ ? [
51
+ {
52
+ actual: { characterCount: source.length, kind: "character_count", source },
53
+ affectedOccurrences: occurrences.map(affectedOccurrence),
54
+ expectation: {
55
+ kind: "maximum_characters",
56
+ maximumCharacters: options.rule.maximumCharacters
57
+ },
58
+ kind: "character_budget",
59
+ recovery: options.rule.recovery,
60
+ role: options.role.id,
61
+ ruleId: options.rule.id,
62
+ textUnitId: options.unit.id
63
+ }
64
+ ]
65
+ : []);
66
+ }
67
+ function escapedRegExp(value) {
68
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
69
+ }
70
+ function termMatches(source, term, caseSensitive) {
71
+ const expression = new RegExp(escapedRegExp(term), caseSensitive ? "gu" : "giu");
72
+ return [...source.matchAll(expression)].map((match) => ({
73
+ end: (match.index ?? 0) + match[0].length,
74
+ matched: match[0],
75
+ start: match.index ?? 0
76
+ }));
77
+ }
78
+ function terminologyFindings(options) {
79
+ const entries = [...options.rule.terms].sort((left, right) => {
80
+ const leftKey = left.kind === "forbidden" ? `0:${left.term}` : `1:${left.term}`;
81
+ const rightKey = right.kind === "forbidden" ? `0:${right.term}` : `1:${right.term}`;
82
+ return leftKey.localeCompare(rightKey);
83
+ });
84
+ return occurrenceGroups(options.unit, options.role).flatMap(({ occurrences, source }) => entries.flatMap((entry) => {
85
+ const discouraged = entry.kind === "forbidden" ? [entry.term] : [...entry.alternatives].sort();
86
+ return discouraged.flatMap((term) => termMatches(source, term, options.rule.caseSensitive).map((match) => ({
87
+ actual: {
88
+ end: match.end,
89
+ kind: "terminology_match",
90
+ source,
91
+ start: match.start,
92
+ term: match.matched
93
+ },
94
+ affectedOccurrences: occurrences.map(affectedOccurrence),
95
+ expectation: entry.kind === "forbidden"
96
+ ? { kind: "forbidden_term", term: entry.term }
97
+ : {
98
+ discouragedTerm: term,
99
+ kind: "preferred_term",
100
+ preferredTerm: entry.term
101
+ },
102
+ kind: "terminology",
103
+ recovery: options.rule.recovery,
104
+ role: options.role.id,
105
+ ruleId: options.rule.id,
106
+ textUnitId: options.unit.id
107
+ })));
108
+ }));
109
+ }
110
+ function findingsForRule(options) {
111
+ return options.units.flatMap((unit) => options.rule.kind === "character_budget"
112
+ ? characterBudgetFindings({ role: options.role, rule: options.rule, unit })
113
+ : terminologyFindings({ role: options.role, rule: options.rule, unit }));
114
+ }
115
+ /** Pure quality evaluation over an already-built TextCorpus. */
116
+ export function evaluateTextQuality(corpus, document) {
117
+ const units = [...corpus.units].sort((left, right) => left.id.localeCompare(right.id));
118
+ const roles = [...document.roles].sort((left, right) => left.id.localeCompare(right.id));
119
+ const roleById = new Map(roles.map((role) => [role.id, role]));
120
+ const rules = [...document.rules].sort((left, right) => left.id.localeCompare(right.id));
121
+ const findings = rules.flatMap((rule) => {
122
+ const role = roleById.get(rule.role);
123
+ if (role === undefined)
124
+ return [];
125
+ return findingsForRule({ role, rule, units });
126
+ });
127
+ return {
128
+ coverage: corpus.coverage,
129
+ diagnostics: corpus.diagnostics,
130
+ findings,
131
+ roles: roles.map((role) => {
132
+ const matchedUnits = units.filter((unit) => unit.occurrences.some((occurrence) => matchesTextRole(occurrence, role)));
133
+ return {
134
+ matchedOccurrences: matchedUnits.reduce((count, unit) => count +
135
+ unit.occurrences.filter((occurrence) => matchesTextRole(occurrence, role))
136
+ .length, 0),
137
+ matchedTextUnits: matchedUnits.length,
138
+ role: role.id
139
+ };
140
+ }),
141
+ ruleDocumentVersion: document.schemaVersion,
142
+ rules: rules.map((rule) => ({
143
+ findingCount: findings.filter((finding) => finding.ruleId === rule.id).length,
144
+ ruleId: rule.id
145
+ })),
146
+ schemaVersion: 1,
147
+ status: corpus.status
148
+ };
149
+ }
150
+ //# sourceMappingURL=quality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.js","sourceRoot":"","sources":["../src/quality.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { TextCorpus, TextCorpusFocus, TextCorpusFocusRequest, TextCorpusQuerySummary, TextCorpusSearchPage, TextCorpusSearchRequest } from "./schema.js";
2
+ /**
3
+ * In-memory, query-scoped view of a compact text corpus. It normalizes every unit once at refresh
4
+ * time and emits only bounded pages to callers.
5
+ */
6
+ export interface TextCorpusQuery {
7
+ readonly focus: (request: TextCorpusFocusRequest) => TextCorpusFocus | undefined;
8
+ readonly search: (request: TextCorpusSearchRequest) => TextCorpusSearchPage;
9
+ readonly summary: () => TextCorpusQuerySummary;
10
+ }
11
+ export declare function textCorpusQuery(corpus: TextCorpus): TextCorpusQuery;
12
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EAMvB,MAAM,aAAa,CAAC;AAgErB;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,eAAe,GAAG,SAAS,CAAC;IACjF,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,oBAAoB,CAAC;IAC5E,QAAQ,CAAC,OAAO,EAAE,MAAM,sBAAsB,CAAC;CAC/C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,eAAe,CAuHnE"}
package/dist/query.js ADDED
@@ -0,0 +1,155 @@
1
+ import { hasSearchableSource, searchableSourceText } from "./search.js";
2
+ function normalizedTerms(query) {
3
+ return query.toLocaleLowerCase().trim().split(/\s+/u).filter(Boolean);
4
+ }
5
+ const LONG_SOURCE_THRESHOLD = 40;
6
+ function sourceValue(unit) {
7
+ return unit.source.status === "consistent" ? unit.source.value : unit.source.values.join(" ");
8
+ }
9
+ function wordCount(value) {
10
+ return value.trim() === "" ? 0 : value.trim().split(/\s+/u).length;
11
+ }
12
+ function searchResult(unit, duplicateSources) {
13
+ const contexts = unit.occurrences.slice(0, 3).map((occurrence) => ({
14
+ editCapability: occurrence.editCapability,
15
+ location: occurrence.location
16
+ }));
17
+ const value = sourceValue(unit);
18
+ const reviewSignals = [];
19
+ if (unit.occurrences.length > 1)
20
+ reviewSignals.push("shared");
21
+ if (unit.source.status === "consistent" && duplicateSources.has(unit.source.value))
22
+ reviewSignals.push("duplicate_source");
23
+ if (value.length >= LONG_SOURCE_THRESHOLD)
24
+ reviewSignals.push("long");
25
+ if (unit.identity.status === "unresolved")
26
+ reviewSignals.push("unresolved");
27
+ if (unit.source.status === "conflicting")
28
+ reviewSignals.push("conflicting");
29
+ if (unit.occurrences.every((occurrence) => occurrence.editCapability === "read_only"))
30
+ reviewSignals.push("evidence_only");
31
+ return {
32
+ characterCount: value.length,
33
+ contexts,
34
+ id: unit.id,
35
+ identity: unit.identity,
36
+ locationKinds: [
37
+ ...new Set(unit.occurrences.map((occurrence) => occurrence.location.kind))
38
+ ].sort(),
39
+ occurrenceCount: unit.occurrences.length,
40
+ remainingContextCount: Math.max(0, unit.occurrences.length - contexts.length),
41
+ reviewSignals,
42
+ source: unit.source,
43
+ wordCount: wordCount(value)
44
+ };
45
+ }
46
+ function matchesLens(signals, lens) {
47
+ if (lens === undefined || lens === "all")
48
+ return true;
49
+ return signals.includes(lens);
50
+ }
51
+ function filteredOccurrences(unit, capability) {
52
+ if (capability === "all")
53
+ return unit.occurrences;
54
+ return unit.occurrences.filter((occurrence) => occurrence.editCapability === capability);
55
+ }
56
+ export function textCorpusQuery(corpus) {
57
+ const units = [...corpus.units].sort((left, right) => left.id.localeCompare(right.id));
58
+ const sourceFrequency = new Map();
59
+ for (const unit of units) {
60
+ if (unit.source.status !== "consistent")
61
+ continue;
62
+ sourceFrequency.set(unit.source.value, (sourceFrequency.get(unit.source.value) ?? 0) + 1);
63
+ }
64
+ const duplicateSources = new Set([...sourceFrequency].filter(([, count]) => count > 1).map(([source]) => source));
65
+ const indexed = units.map((unit) => ({
66
+ presentation: searchResult(unit, duplicateSources),
67
+ searchable: searchableSourceText(unit),
68
+ unit
69
+ }));
70
+ const diagnosticsByPackage = new Map();
71
+ for (const diagnostic of corpus.diagnostics) {
72
+ diagnosticsByPackage.set(diagnostic.packageFile, [
73
+ ...(diagnosticsByPackage.get(diagnostic.packageFile) ?? []),
74
+ diagnostic
75
+ ]);
76
+ }
77
+ const summary = {
78
+ schemaVersion: 1,
79
+ status: corpus.status,
80
+ coverage: corpus.coverage,
81
+ diagnosticCount: corpus.diagnostics.length,
82
+ review: {
83
+ all: indexed.length,
84
+ shared: indexed.filter(({ presentation }) => presentation.reviewSignals.includes("shared")).length,
85
+ duplicateSource: indexed.filter(({ presentation }) => presentation.reviewSignals.includes("duplicate_source")).length,
86
+ long: indexed.filter(({ presentation }) => presentation.reviewSignals.includes("long"))
87
+ .length,
88
+ unresolved: indexed.filter(({ presentation }) => presentation.reviewSignals.includes("unresolved")).length,
89
+ conflicting: indexed.filter(({ presentation }) => presentation.reviewSignals.includes("conflicting")).length
90
+ },
91
+ sources: {
92
+ assetProperty: indexed.filter(({ presentation }) => presentation.locationKinds.includes("asset_property")).length,
93
+ dataTable: indexed.filter(({ presentation }) => presentation.locationKinds.includes("data_table_cell")).length,
94
+ mixed: indexed.filter(({ presentation }) => presentation.locationKinds.length > 1)
95
+ .length,
96
+ stringTable: indexed.filter(({ presentation }) => presentation.locationKinds.includes("string_table_entry")).length
97
+ }
98
+ };
99
+ return {
100
+ summary: () => summary,
101
+ search: (request) => {
102
+ const terms = normalizedTerms(request.query);
103
+ const matched = indexed.filter(({ presentation, searchable, unit }) => {
104
+ if (!hasSearchableSource(unit))
105
+ return false;
106
+ if (filteredOccurrences(unit, request.capability).length === 0)
107
+ return false;
108
+ if (!matchesLens(presentation.reviewSignals, request.lens))
109
+ return false;
110
+ return terms.every((term) => searchable.includes(term));
111
+ });
112
+ const afterCursor = request.cursor
113
+ ? matched.findIndex(({ unit }) => unit.id === request.cursor) + 1
114
+ : 0;
115
+ const page = matched.slice(Math.max(0, afterCursor), afterCursor + request.pageSize);
116
+ const final = page.at(-1)?.unit.id;
117
+ return {
118
+ total: matched.length,
119
+ units: page.map(({ presentation }) => presentation),
120
+ ...(final !== undefined && afterCursor + page.length < matched.length
121
+ ? { nextCursor: final }
122
+ : {})
123
+ };
124
+ },
125
+ focus: (request) => {
126
+ const unit = units.find((candidate) => candidate.id === request.id);
127
+ if (!unit)
128
+ return undefined;
129
+ const afterCursor = request.occurrenceCursor
130
+ ? unit.occurrences.findIndex((occurrence) => occurrence.id === request.occurrenceCursor) + 1
131
+ : 0;
132
+ const occurrences = unit.occurrences.slice(Math.max(0, afterCursor), afterCursor + request.pageSize);
133
+ const final = occurrences.at(-1)?.id;
134
+ const diagnostics = [
135
+ ...new Map(unit.occurrences
136
+ .flatMap((occurrence) => diagnosticsByPackage.get(occurrence.packageFile) ?? [])
137
+ .map((diagnostic) => [
138
+ `${diagnostic.code}:${diagnostic.packageFile}:${diagnostic.objectPath ?? ""}:${diagnostic.propertyPath ?? ""}`,
139
+ diagnostic
140
+ ])).values()
141
+ ].slice(0, request.pageSize);
142
+ return {
143
+ diagnostics,
144
+ occurrences,
145
+ totalOccurrences: unit.occurrences.length,
146
+ unit: searchResult(unit, duplicateSources),
147
+ ...(final !== undefined &&
148
+ afterCursor + occurrences.length < unit.occurrences.length
149
+ ? { nextOccurrenceCursor: final }
150
+ : {})
151
+ };
152
+ }
153
+ };
154
+ }
155
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}