@mrtdown/core 2.0.0-alpha.1 → 2.0.0-alpha.10
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/helpers/normalizeRecurringPeriod.d.ts +1 -1
- package/dist/helpers/normalizeRecurringPeriod.js +1 -1
- package/dist/helpers/normalizeRecurringPeriod.js.map +1 -1
- package/dist/helpers/normalizeRecurringPeriod.test.js.map +1 -1
- package/dist/helpers/resolvePeriods.d.ts +20 -5
- package/dist/helpers/resolvePeriods.js +15 -1
- package/dist/helpers/resolvePeriods.js.map +1 -1
- package/dist/helpers/resolvePeriods.test.js.map +1 -1
- package/dist/index.d.ts +22 -18
- package/dist/index.js +22 -18
- package/dist/index.js.map +1 -1
- package/dist/schema/Landmark.js.map +1 -1
- package/dist/schema/Line.d.ts +6 -0
- package/dist/schema/Line.js +2 -1
- package/dist/schema/Line.js.map +1 -1
- package/dist/schema/Operator.js.map +1 -1
- package/dist/schema/Service.js.map +1 -1
- package/dist/schema/Station.d.ts +7 -0
- package/dist/schema/Station.js +7 -6
- package/dist/schema/Station.js.map +1 -1
- package/dist/schema/Town.js.map +1 -1
- package/dist/schema/common.d.ts +4 -0
- package/dist/schema/common.js +3 -0
- package/dist/schema/common.js.map +1 -1
- package/dist/schema/issue/bundle.js.map +1 -1
- package/dist/schema/issue/cause.js.map +1 -1
- package/dist/schema/issue/claim.js.map +1 -1
- package/dist/schema/issue/entity.d.ts +6 -0
- package/dist/schema/issue/entity.js +6 -1
- package/dist/schema/issue/entity.js.map +1 -1
- package/dist/schema/issue/evidence.d.ts +6 -0
- package/dist/schema/issue/evidence.js +9 -4
- package/dist/schema/issue/evidence.js.map +1 -1
- package/dist/schema/issue/facilityEffect.d.ts +5 -0
- package/dist/schema/issue/facilityEffect.js +6 -2
- package/dist/schema/issue/facilityEffect.js.map +1 -1
- package/dist/schema/issue/id.js.map +1 -1
- package/dist/schema/issue/impactEvent.js.map +1 -1
- package/dist/schema/issue/issue.js +2 -4
- package/dist/schema/issue/issue.js.map +1 -1
- package/dist/schema/issue/issueType.js.map +1 -1
- package/dist/schema/issue/period.js.map +1 -1
- package/dist/schema/issue/serviceEffect.d.ts +7 -0
- package/dist/schema/issue/serviceEffect.js +10 -4
- package/dist/schema/issue/serviceEffect.js.map +1 -1
- package/dist/schema/issue/serviceScope.d.ts +6 -0
- package/dist/schema/issue/serviceScope.js +8 -3
- package/dist/schema/issue/serviceScope.js.map +1 -1
- package/dist/util/assert.js.map +1 -1
- package/package.json +21 -61
- package/README.md +0 -107
- package/dist/constants.d.ts +0 -10
- package/dist/constants.js +0 -11
- package/dist/constants.js.map +0 -1
- package/dist/helpers/calculateDurationWithinServiceHours.d.ts +0 -2
- package/dist/helpers/calculateDurationWithinServiceHours.js +0 -13
- package/dist/helpers/calculateDurationWithinServiceHours.js.map +0 -1
- package/dist/helpers/calculateDurationWithinServiceHours.test.d.ts +0 -1
- package/dist/helpers/calculateDurationWithinServiceHours.test.js +0 -83
- package/dist/helpers/calculateDurationWithinServiceHours.test.js.map +0 -1
- package/dist/helpers/computeImpactFromEvidenceClaims.d.ts +0 -21
- package/dist/helpers/computeImpactFromEvidenceClaims.js +0 -293
- package/dist/helpers/computeImpactFromEvidenceClaims.js.map +0 -1
- package/dist/helpers/computeImpactFromEvidenceClaims.test.d.ts +0 -1
- package/dist/helpers/computeImpactFromEvidenceClaims.test.js +0 -544
- package/dist/helpers/computeImpactFromEvidenceClaims.test.js.map +0 -1
- package/dist/helpers/computeStartOfDaysWithinInterval.d.ts +0 -2
- package/dist/helpers/computeStartOfDaysWithinInterval.js +0 -15
- package/dist/helpers/computeStartOfDaysWithinInterval.js.map +0 -1
- package/dist/helpers/computeStartOfDaysWithinInterval.test.d.ts +0 -1
- package/dist/helpers/computeStartOfDaysWithinInterval.test.js +0 -126
- package/dist/helpers/computeStartOfDaysWithinInterval.test.js.map +0 -1
- package/dist/helpers/estimateOpenAICost.d.ts +0 -40
- package/dist/helpers/estimateOpenAICost.js +0 -55
- package/dist/helpers/estimateOpenAICost.js.map +0 -1
- package/dist/helpers/keyForAffectedEntity.d.ts +0 -7
- package/dist/helpers/keyForAffectedEntity.js +0 -14
- package/dist/helpers/keyForAffectedEntity.js.map +0 -1
- package/dist/helpers/splitIntervalByServiceHours.d.ts +0 -2
- package/dist/helpers/splitIntervalByServiceHours.js +0 -30
- package/dist/helpers/splitIntervalByServiceHours.js.map +0 -1
- package/dist/helpers/splitIntervalByServiceHours.test.d.ts +0 -1
- package/dist/helpers/splitIntervalByServiceHours.test.js +0 -152
- package/dist/helpers/splitIntervalByServiceHours.test.js.map +0 -1
- package/dist/helpers/sumIntervalDuration.d.ts +0 -2
- package/dist/helpers/sumIntervalDuration.js +0 -9
- package/dist/helpers/sumIntervalDuration.js.map +0 -1
- package/dist/repo/MRTDownRepository.d.ts +0 -23
- package/dist/repo/MRTDownRepository.js +0 -28
- package/dist/repo/MRTDownRepository.js.map +0 -1
- package/dist/repo/common/FileStore.d.ts +0 -12
- package/dist/repo/common/FileStore.js +0 -27
- package/dist/repo/common/FileStore.js.map +0 -1
- package/dist/repo/common/StandardRepository.d.ts +0 -32
- package/dist/repo/common/StandardRepository.js +0 -58
- package/dist/repo/common/StandardRepository.js.map +0 -1
- package/dist/repo/common/store.d.ts +0 -29
- package/dist/repo/common/store.js +0 -2
- package/dist/repo/common/store.js.map +0 -1
- package/dist/repo/issue/IssueRepository.d.ts +0 -36
- package/dist/repo/issue/IssueRepository.js +0 -177
- package/dist/repo/issue/IssueRepository.js.map +0 -1
- package/dist/repo/issue/helpers/deriveCurrentState.d.ts +0 -51
- package/dist/repo/issue/helpers/deriveCurrentState.js +0 -113
- package/dist/repo/issue/helpers/deriveCurrentState.js.map +0 -1
- package/dist/repo/issue/helpers/deriveCurrentState.test.d.ts +0 -1
- package/dist/repo/issue/helpers/deriveCurrentState.test.js +0 -477
- package/dist/repo/issue/helpers/deriveCurrentState.test.js.map +0 -1
- package/dist/repo/landmark/LandmarkRepository.d.ts +0 -7
- package/dist/repo/landmark/LandmarkRepository.js +0 -12
- package/dist/repo/landmark/LandmarkRepository.js.map +0 -1
- package/dist/repo/line/LineRepository.d.ts +0 -13
- package/dist/repo/line/LineRepository.js +0 -32
- package/dist/repo/line/LineRepository.js.map +0 -1
- package/dist/repo/operator/OperatorRepository.d.ts +0 -7
- package/dist/repo/operator/OperatorRepository.js +0 -12
- package/dist/repo/operator/OperatorRepository.js.map +0 -1
- package/dist/repo/service/ServiceRepository.d.ts +0 -19
- package/dist/repo/service/ServiceRepository.js +0 -39
- package/dist/repo/service/ServiceRepository.js.map +0 -1
- package/dist/repo/station/StationRepository.d.ts +0 -13
- package/dist/repo/station/StationRepository.js +0 -30
- package/dist/repo/station/StationRepository.js.map +0 -1
- package/dist/repo/town/TownRepository.d.ts +0 -7
- package/dist/repo/town/TownRepository.js +0 -12
- package/dist/repo/town/TownRepository.js.map +0 -1
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.d.ts +0 -7
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js +0 -24
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js.map +0 -1
- package/dist/util/ingestContent/index.d.ts +0 -12
- package/dist/util/ingestContent/index.js +0 -171
- package/dist/util/ingestContent/index.js.map +0 -1
- package/dist/util/ingestContent/types.d.ts +0 -32
- package/dist/util/ingestContent/types.js +0 -2
- package/dist/util/ingestContent/types.js.map +0 -1
- package/dist/write/MRTDownWriter.d.ts +0 -27
- package/dist/write/MRTDownWriter.js +0 -27
- package/dist/write/MRTDownWriter.js.map +0 -1
- package/dist/write/common/FileWriteStore.d.ts +0 -13
- package/dist/write/common/FileWriteStore.js +0 -31
- package/dist/write/common/FileWriteStore.js.map +0 -1
- package/dist/write/common/StandardWriter.d.ts +0 -14
- package/dist/write/common/StandardWriter.js +0 -17
- package/dist/write/common/StandardWriter.js.map +0 -1
- package/dist/write/common/store.d.ts +0 -32
- package/dist/write/common/store.js +0 -2
- package/dist/write/common/store.js.map +0 -1
- package/dist/write/id/IdGenerator.d.ts +0 -18
- package/dist/write/id/IdGenerator.js +0 -23
- package/dist/write/id/IdGenerator.js.map +0 -1
- package/dist/write/issue/IssueWriter.d.ts +0 -12
- package/dist/write/issue/IssueWriter.js +0 -33
- package/dist/write/issue/IssueWriter.js.map +0 -1
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { IStore } from './store.js';
|
|
2
|
-
type Item = {
|
|
3
|
-
id: string;
|
|
4
|
-
};
|
|
5
|
-
/**
|
|
6
|
-
* A standard repository for items represented by single JSON files that are stored in a directory.
|
|
7
|
-
*/
|
|
8
|
-
export declare class StandardRepository<T extends Item> {
|
|
9
|
-
protected store: IStore;
|
|
10
|
-
protected dirPath: string;
|
|
11
|
-
protected byId: Map<string, T>;
|
|
12
|
-
protected loaded: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Create a new standard repository.
|
|
15
|
-
* @param store
|
|
16
|
-
*/
|
|
17
|
-
constructor(store: IStore, dirPath: string);
|
|
18
|
-
/**
|
|
19
|
-
* Load all items from the directory.
|
|
20
|
-
*/
|
|
21
|
-
protected loadAll(): void;
|
|
22
|
-
protected parseItem(_json: unknown): T;
|
|
23
|
-
/**
|
|
24
|
-
* Get an item by ID.
|
|
25
|
-
*/
|
|
26
|
-
get(id: string): T | null;
|
|
27
|
-
/**
|
|
28
|
-
* List all items.
|
|
29
|
-
*/
|
|
30
|
-
list(): T[];
|
|
31
|
-
}
|
|
32
|
-
export {};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { join } from 'node:path';
|
|
2
|
-
/**
|
|
3
|
-
* A standard repository for items represented by single JSON files that are stored in a directory.
|
|
4
|
-
*/
|
|
5
|
-
export class StandardRepository {
|
|
6
|
-
store;
|
|
7
|
-
dirPath;
|
|
8
|
-
byId = new Map();
|
|
9
|
-
loaded = false;
|
|
10
|
-
/**
|
|
11
|
-
* Create a new standard repository.
|
|
12
|
-
* @param store
|
|
13
|
-
*/
|
|
14
|
-
constructor(store, dirPath) {
|
|
15
|
-
this.store = store;
|
|
16
|
-
this.dirPath = dirPath;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Load all items from the directory.
|
|
20
|
-
*/
|
|
21
|
-
loadAll() {
|
|
22
|
-
if (this.loaded) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
const dirFiles = this.store.listDir(this.dirPath);
|
|
26
|
-
for (const fileName of dirFiles) {
|
|
27
|
-
const filePath = join(this.dirPath, fileName);
|
|
28
|
-
const json = this.store.readJson(filePath);
|
|
29
|
-
try {
|
|
30
|
-
const item = this.parseItem(json);
|
|
31
|
-
this.byId.set(item.id, item);
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
console.error(`Error parsing ${filePath}: ${error}`);
|
|
35
|
-
throw error;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
this.loaded = true;
|
|
39
|
-
}
|
|
40
|
-
parseItem(_json) {
|
|
41
|
-
throw new Error('Not implemented');
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Get an item by ID.
|
|
45
|
-
*/
|
|
46
|
-
get(id) {
|
|
47
|
-
this.loadAll();
|
|
48
|
-
return this.byId.get(id) ?? null;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* List all items.
|
|
52
|
-
*/
|
|
53
|
-
list() {
|
|
54
|
-
this.loadAll();
|
|
55
|
-
return Array.from(this.byId.values());
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=StandardRepository.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StandardRepository.js","sourceRoot":"/","sources":["repo/common/StandardRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAOjC;;GAEG;AACH,MAAM,OAAO,kBAAkB;IACnB,KAAK,CAAS;IACd,OAAO,CAAS;IAChB,IAAI,GAAG,IAAI,GAAG,EAAa,CAAC;IAC5B,MAAM,GAAG,KAAK,CAAC;IAEzB;;;OAGG;IACH,YAAY,KAAa,EAAE,OAAe;QACxC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;OAEG;IACO,OAAO;QACf,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClD,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,iBAAiB,QAAQ,KAAK,KAAK,EAAE,CAAC,CAAC;gBACrD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAES,SAAS,CAAC,KAAc;QAChC,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,EAAU;QACZ,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;CACF","sourcesContent":["import { join } from 'node:path';\nimport type { IStore } from './store.js';\n\ntype Item = {\n id: string;\n};\n\n/**\n * A standard repository for items represented by single JSON files that are stored in a directory.\n */\nexport class StandardRepository<T extends Item> {\n protected store: IStore;\n protected dirPath: string;\n protected byId = new Map<string, T>();\n protected loaded = false;\n\n /**\n * Create a new standard repository.\n * @param store\n */\n constructor(store: IStore, dirPath: string) {\n this.store = store;\n this.dirPath = dirPath;\n }\n\n /**\n * Load all items from the directory.\n */\n protected loadAll() {\n if (this.loaded) {\n return;\n }\n\n const dirFiles = this.store.listDir(this.dirPath);\n for (const fileName of dirFiles) {\n const filePath = join(this.dirPath, fileName);\n const json = this.store.readJson(filePath);\n try {\n const item = this.parseItem(json);\n this.byId.set(item.id, item);\n } catch (error) {\n console.error(`Error parsing ${filePath}: ${error}`);\n throw error;\n }\n }\n\n this.loaded = true;\n }\n\n protected parseItem(_json: unknown): T {\n throw new Error('Not implemented');\n }\n\n /**\n * Get an item by ID.\n */\n get(id: string): T | null {\n this.loadAll();\n return this.byId.get(id) ?? null;\n }\n\n /**\n * List all items.\n */\n list(): T[] {\n this.loadAll();\n return Array.from(this.byId.values());\n }\n}\n"]}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A store for reading and writing files.
|
|
3
|
-
*/
|
|
4
|
-
export interface IStore {
|
|
5
|
-
/**
|
|
6
|
-
* Read a text file.
|
|
7
|
-
* @param path
|
|
8
|
-
* @returns
|
|
9
|
-
*/
|
|
10
|
-
readText(path: string): string;
|
|
11
|
-
/**
|
|
12
|
-
* Read a JSON file.
|
|
13
|
-
* @param path
|
|
14
|
-
* @returns
|
|
15
|
-
*/
|
|
16
|
-
readJson<T>(path: string): T;
|
|
17
|
-
/**
|
|
18
|
-
* List all files in a directory.
|
|
19
|
-
* @param path
|
|
20
|
-
* @returns
|
|
21
|
-
*/
|
|
22
|
-
listDir(path: string): string[];
|
|
23
|
-
/**
|
|
24
|
-
* Check if a file exists.
|
|
25
|
-
* @param path
|
|
26
|
-
* @returns
|
|
27
|
-
*/
|
|
28
|
-
exists(path: string): boolean;
|
|
29
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"/","sources":["repo/common/store.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * A store for reading and writing files.\n */\nexport interface IStore {\n /**\n * Read a text file.\n * @param path\n * @returns\n */\n readText(path: string): string;\n /**\n * Read a JSON file.\n * @param path\n * @returns\n */\n readJson<T>(path: string): T;\n /**\n * List all files in a directory.\n * @param path\n * @returns\n */\n listDir(path: string): string[];\n /**\n * Check if a file exists.\n * @param path\n * @returns\n */\n exists(path: string): boolean;\n}\n"]}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { IssueBundle } from '#schema/issue/bundle.js';
|
|
2
|
-
import type { IStore } from '../common/store.js';
|
|
3
|
-
export declare class IssueRepository {
|
|
4
|
-
private readonly store;
|
|
5
|
-
constructor(store: IStore);
|
|
6
|
-
private byId;
|
|
7
|
-
private indexed;
|
|
8
|
-
private bundleCache;
|
|
9
|
-
/**
|
|
10
|
-
* Build the index of all issues.
|
|
11
|
-
*/
|
|
12
|
-
private buildIndex;
|
|
13
|
-
/**
|
|
14
|
-
* Return the relative folder path to the issue.
|
|
15
|
-
* @param id
|
|
16
|
-
* @returns
|
|
17
|
-
*/
|
|
18
|
-
getPath(id: string): string | null;
|
|
19
|
-
get(id: string): IssueBundle | null;
|
|
20
|
-
/**
|
|
21
|
-
* List all issue IDs, sorted by year and month.
|
|
22
|
-
* @returns
|
|
23
|
-
*/
|
|
24
|
-
listIds(): string[];
|
|
25
|
-
/**
|
|
26
|
-
* List all bundles, sorted by year and month.
|
|
27
|
-
* @returns
|
|
28
|
-
*/
|
|
29
|
-
list(): IssueBundle[];
|
|
30
|
-
/**
|
|
31
|
-
* Search issues by query.
|
|
32
|
-
* @param query
|
|
33
|
-
* @returns
|
|
34
|
-
*/
|
|
35
|
-
searchByQuery(query: string): IssueBundle[];
|
|
36
|
-
}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import { join } from 'node:path';
|
|
2
|
-
import Fuse from 'fuse.js';
|
|
3
|
-
import { NdJson } from 'json-nd';
|
|
4
|
-
import z from 'zod';
|
|
5
|
-
import { EvidenceSchema } from '#schema/issue/evidence.js';
|
|
6
|
-
import { ImpactEventSchema } from '#schema/issue/impactEvent.js';
|
|
7
|
-
import { IssueSchema } from '#schema/issue/issue.js';
|
|
8
|
-
import { DIR_ISSUE } from '../../constants.js';
|
|
9
|
-
export class IssueRepository {
|
|
10
|
-
store;
|
|
11
|
-
constructor(store) {
|
|
12
|
-
this.store = store;
|
|
13
|
-
}
|
|
14
|
-
// Index for fast lookup by issue ID.
|
|
15
|
-
byId = new Map();
|
|
16
|
-
indexed = false;
|
|
17
|
-
// Cache for issue bundles.
|
|
18
|
-
bundleCache = new Map();
|
|
19
|
-
/**
|
|
20
|
-
* Build the index of all issues.
|
|
21
|
-
*/
|
|
22
|
-
buildIndex() {
|
|
23
|
-
if (this.indexed) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const years = this.store.listDir(DIR_ISSUE);
|
|
27
|
-
for (const year of years) {
|
|
28
|
-
if (!/^\d{4}$/.test(year)) {
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
const months = this.store.listDir(join(DIR_ISSUE, year));
|
|
32
|
-
for (const month of months) {
|
|
33
|
-
if (!/^\d{2}$/.test(month)) {
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
const issues = this.store.listDir(join(DIR_ISSUE, year, month));
|
|
37
|
-
for (const issueId of issues) {
|
|
38
|
-
this.byId.set(issueId, {
|
|
39
|
-
issueId: issueId,
|
|
40
|
-
path: join(DIR_ISSUE, year, month, issueId),
|
|
41
|
-
year: Number(year),
|
|
42
|
-
month: Number(month),
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
this.indexed = true;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Return the relative folder path to the issue.
|
|
51
|
-
* @param id
|
|
52
|
-
* @returns
|
|
53
|
-
*/
|
|
54
|
-
getPath(id) {
|
|
55
|
-
this.buildIndex();
|
|
56
|
-
return this.byId.get(id)?.path ?? null;
|
|
57
|
-
}
|
|
58
|
-
get(id) {
|
|
59
|
-
this.buildIndex();
|
|
60
|
-
const isCached = this.bundleCache.has(id);
|
|
61
|
-
if (isCached) {
|
|
62
|
-
return this.bundleCache.get(id) ?? null;
|
|
63
|
-
}
|
|
64
|
-
const entry = this.byId.get(id);
|
|
65
|
-
if (!entry) {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
const issue = IssueSchema.parse(this.store.readJson(join(entry.path, 'issue.json')));
|
|
69
|
-
const evidencePath = join(entry.path, 'evidence.ndjson');
|
|
70
|
-
const evidenceRaw = this.store.exists(evidencePath)
|
|
71
|
-
? this.store.readText(evidencePath).trim()
|
|
72
|
-
: '';
|
|
73
|
-
const evidence = z
|
|
74
|
-
.array(EvidenceSchema)
|
|
75
|
-
.parse(evidenceRaw ? NdJson.parse(evidenceRaw) : []);
|
|
76
|
-
const impactPath = join(entry.path, 'impact.ndjson');
|
|
77
|
-
const impactRaw = this.store.exists(impactPath)
|
|
78
|
-
? this.store.readText(impactPath).trim()
|
|
79
|
-
: '';
|
|
80
|
-
const impact = z
|
|
81
|
-
.array(ImpactEventSchema)
|
|
82
|
-
.parse(impactRaw ? NdJson.parse(impactRaw) : []);
|
|
83
|
-
const bundle = {
|
|
84
|
-
issue,
|
|
85
|
-
evidence,
|
|
86
|
-
impactEvents: impact,
|
|
87
|
-
path: entry.path,
|
|
88
|
-
};
|
|
89
|
-
this.bundleCache.set(id, bundle);
|
|
90
|
-
return bundle;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* List all issue IDs, sorted by year and month.
|
|
94
|
-
* @returns
|
|
95
|
-
*/
|
|
96
|
-
listIds() {
|
|
97
|
-
this.buildIndex();
|
|
98
|
-
const entries = Array.from(this.byId.values());
|
|
99
|
-
entries.sort((a, b) => {
|
|
100
|
-
if (a.year !== b.year) {
|
|
101
|
-
return a.year - b.year;
|
|
102
|
-
}
|
|
103
|
-
if (a.month !== b.month) {
|
|
104
|
-
return a.month - b.month;
|
|
105
|
-
}
|
|
106
|
-
return a.issueId.localeCompare(b.issueId);
|
|
107
|
-
});
|
|
108
|
-
return entries.map((entry) => entry.issueId);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* List all bundles, sorted by year and month.
|
|
112
|
-
* @returns
|
|
113
|
-
*/
|
|
114
|
-
list() {
|
|
115
|
-
this.buildIndex();
|
|
116
|
-
const entries = Array.from(this.byId.values());
|
|
117
|
-
entries.sort((a, b) => {
|
|
118
|
-
if (a.year !== b.year) {
|
|
119
|
-
return a.year - b.year;
|
|
120
|
-
}
|
|
121
|
-
if (a.month !== b.month) {
|
|
122
|
-
return a.month - b.month;
|
|
123
|
-
}
|
|
124
|
-
return a.issueId.localeCompare(b.issueId);
|
|
125
|
-
});
|
|
126
|
-
const result = [];
|
|
127
|
-
for (const entry of entries) {
|
|
128
|
-
const bundle = this.get(entry.issueId);
|
|
129
|
-
if (bundle == null) {
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
result.push(bundle);
|
|
133
|
-
}
|
|
134
|
-
return result;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Search issues by query.
|
|
138
|
-
* @param query
|
|
139
|
-
* @returns
|
|
140
|
-
*/
|
|
141
|
-
searchByQuery(query) {
|
|
142
|
-
const fuse = new Fuse(this.list(), {
|
|
143
|
-
keys: [
|
|
144
|
-
'issue.id',
|
|
145
|
-
'issue.title.en-SG',
|
|
146
|
-
'evidence.text',
|
|
147
|
-
'impact.scopeItems.serviceId',
|
|
148
|
-
'impact.scopeItems.stationId',
|
|
149
|
-
'impact.scopeItems.fromStationId',
|
|
150
|
-
'impact.scopeItems.toStationId',
|
|
151
|
-
],
|
|
152
|
-
includeScore: true,
|
|
153
|
-
threshold: 0.8,
|
|
154
|
-
});
|
|
155
|
-
const searchResults = fuse.search({
|
|
156
|
-
$or: [
|
|
157
|
-
{ 'issue.id': query },
|
|
158
|
-
{ 'issue.title.en-SG': query },
|
|
159
|
-
{ 'evidence.text': query },
|
|
160
|
-
{ 'impact.scopeItems.serviceId': query },
|
|
161
|
-
{ 'impact.scopeItems.stationId': query },
|
|
162
|
-
{ 'impact.scopeItems.fromStationId': query },
|
|
163
|
-
{ 'impact.scopeItems.toStationId': query },
|
|
164
|
-
],
|
|
165
|
-
});
|
|
166
|
-
const results = [];
|
|
167
|
-
for (const result of searchResults) {
|
|
168
|
-
const bundle = this.get(result.item.issue.id);
|
|
169
|
-
if (bundle == null) {
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
results.push(bundle);
|
|
173
|
-
}
|
|
174
|
-
return results;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
//# sourceMappingURL=IssueRepository.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IssueRepository.js","sourceRoot":"/","sources":["repo/issue/IssueRepository.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from 'node:path';\nimport Fuse, { type Expression } from 'fuse.js';\nimport { NdJson } from 'json-nd';\nimport z from 'zod';\nimport type { IssueBundle } from '#schema/issue/bundle.js';\nimport { EvidenceSchema } from '#schema/issue/evidence.js';\nimport { ImpactEventSchema } from '#schema/issue/impactEvent.js';\nimport { IssueSchema } from '#schema/issue/issue.js';\nimport { DIR_ISSUE } from '../../constants.js';\nimport type { IStore } from '../common/store.js';\n\ntype IssueIndexEntry = {\n issueId: string;\n path: string; // e.g. data/issues/2026/01/01/<issueId>\n year: number;\n month: number;\n};\n\nexport class IssueRepository {\n private readonly store: IStore;\n\n constructor(store: IStore) {\n this.store = store;\n }\n\n // Index for fast lookup by issue ID.\n private byId = new Map<string, IssueIndexEntry>();\n private indexed = false;\n\n // Cache for issue bundles.\n private bundleCache = new Map<string, IssueBundle>();\n\n /**\n * Build the index of all issues.\n */\n private buildIndex() {\n if (this.indexed) {\n return;\n }\n\n const years = this.store.listDir(DIR_ISSUE);\n for (const year of years) {\n if (!/^\\d{4}$/.test(year)) {\n continue;\n }\n const months = this.store.listDir(join(DIR_ISSUE, year));\n for (const month of months) {\n if (!/^\\d{2}$/.test(month)) {\n continue;\n }\n const issues = this.store.listDir(join(DIR_ISSUE, year, month));\n for (const issueId of issues) {\n this.byId.set(issueId, {\n issueId: issueId,\n path: join(DIR_ISSUE, year, month, issueId),\n year: Number(year),\n month: Number(month),\n });\n }\n }\n }\n this.indexed = true;\n }\n\n /**\n * Return the relative folder path to the issue.\n * @param id\n * @returns\n */\n getPath(id: string): string | null {\n this.buildIndex();\n return this.byId.get(id)?.path ?? null;\n }\n\n get(id: string): IssueBundle | null {\n this.buildIndex();\n\n const isCached = this.bundleCache.has(id);\n if (isCached) {\n return this.bundleCache.get(id) ?? null;\n }\n\n const entry = this.byId.get(id);\n if (!entry) {\n return null;\n }\n\n const issue = IssueSchema.parse(\n this.store.readJson(join(entry.path, 'issue.json')),\n );\n\n const evidencePath = join(entry.path, 'evidence.ndjson');\n const evidenceRaw = this.store.exists(evidencePath)\n ? this.store.readText(evidencePath).trim()\n : '';\n const evidence = z\n .array(EvidenceSchema)\n .parse(evidenceRaw ? NdJson.parse(evidenceRaw) : []);\n\n const impactPath = join(entry.path, 'impact.ndjson');\n const impactRaw = this.store.exists(impactPath)\n ? this.store.readText(impactPath).trim()\n : '';\n const impact = z\n .array(ImpactEventSchema)\n .parse(impactRaw ? NdJson.parse(impactRaw) : []);\n\n const bundle: IssueBundle = {\n issue,\n evidence,\n impactEvents: impact,\n path: entry.path,\n };\n this.bundleCache.set(id, bundle);\n return bundle;\n }\n\n /**\n * List all issue IDs, sorted by year and month.\n * @returns\n */\n listIds(): string[] {\n this.buildIndex();\n const entries = Array.from(this.byId.values());\n entries.sort((a, b) => {\n if (a.year !== b.year) {\n return a.year - b.year;\n }\n if (a.month !== b.month) {\n return a.month - b.month;\n }\n return a.issueId.localeCompare(b.issueId);\n });\n return entries.map((entry) => entry.issueId);\n }\n\n /**\n * List all bundles, sorted by year and month.\n * @returns\n */\n list(): IssueBundle[] {\n this.buildIndex();\n const entries = Array.from(this.byId.values());\n entries.sort((a, b) => {\n if (a.year !== b.year) {\n return a.year - b.year;\n }\n if (a.month !== b.month) {\n return a.month - b.month;\n }\n return a.issueId.localeCompare(b.issueId);\n });\n const result: IssueBundle[] = [];\n for (const entry of entries) {\n const bundle = this.get(entry.issueId);\n if (bundle == null) {\n continue;\n }\n result.push(bundle);\n }\n return result;\n }\n\n /**\n * Search issues by query.\n * @param query\n * @returns\n */\n searchByQuery(query: string): IssueBundle[] {\n const fuse = new Fuse(this.list(), {\n keys: [\n 'issue.id',\n 'issue.title.en-SG',\n 'evidence.text',\n 'impact.scopeItems.serviceId',\n 'impact.scopeItems.stationId',\n 'impact.scopeItems.fromStationId',\n 'impact.scopeItems.toStationId',\n ],\n includeScore: true,\n threshold: 0.8,\n });\n const searchResults = fuse.search({\n $or: [\n { 'issue.id': query },\n { 'issue.title.en-SG': query },\n { 'evidence.text': query },\n { 'impact.scopeItems.serviceId': query },\n { 'impact.scopeItems.stationId': query },\n { 'impact.scopeItems.fromStationId': query },\n { 'impact.scopeItems.toStationId': query },\n ] as Expression[],\n });\n const results: IssueBundle[] = [];\n for (const result of searchResults) {\n const bundle = this.get(result.item.issue.id);\n if (bundle == null) {\n continue;\n }\n results.push(bundle);\n }\n return results;\n }\n}\n"]}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { IssueBundle } from '#schema/issue/bundle.js';
|
|
2
|
-
import type { CauseSubtype } from '#schema/issue/cause.js';
|
|
3
|
-
import type { FacilityEffect } from '#schema/issue/facilityEffect.js';
|
|
4
|
-
import type { Period } from '#schema/issue/period.js';
|
|
5
|
-
import type { ServiceEffect } from '#schema/issue/serviceEffect.js';
|
|
6
|
-
import type { ServiceScope } from '#schema/issue/serviceScope.js';
|
|
7
|
-
type BasisRef = {
|
|
8
|
-
evidenceId: string;
|
|
9
|
-
};
|
|
10
|
-
type ServiceProvenance = {
|
|
11
|
-
effect?: BasisRef;
|
|
12
|
-
scopes?: BasisRef;
|
|
13
|
-
periods?: BasisRef;
|
|
14
|
-
causes?: BasisRef;
|
|
15
|
-
};
|
|
16
|
-
type ServiceState = {
|
|
17
|
-
serviceId: string;
|
|
18
|
-
effect: ServiceEffect | null;
|
|
19
|
-
scopes: ServiceScope[];
|
|
20
|
-
periods: Period[];
|
|
21
|
-
causes: CauseSubtype[];
|
|
22
|
-
};
|
|
23
|
-
type FacilityProvenance = {
|
|
24
|
-
effect?: BasisRef;
|
|
25
|
-
periods?: BasisRef;
|
|
26
|
-
causes?: BasisRef;
|
|
27
|
-
};
|
|
28
|
-
type FacilityState = {
|
|
29
|
-
stationId: string;
|
|
30
|
-
kind: 'lift' | 'escalator' | 'screen-door';
|
|
31
|
-
effect: FacilityEffect | null;
|
|
32
|
-
periods: Period[];
|
|
33
|
-
causes: CauseSubtype[];
|
|
34
|
-
};
|
|
35
|
-
export type IssueBundleState = {
|
|
36
|
-
services: Record<string, ServiceState>;
|
|
37
|
-
servicesProvenance: Record<string, ServiceProvenance>;
|
|
38
|
-
facilities: Record<string, FacilityState>;
|
|
39
|
-
facilitiesProvenance: Record<string, FacilityProvenance>;
|
|
40
|
-
/**
|
|
41
|
-
* The impact event ids that were used to derive the current state.
|
|
42
|
-
*/
|
|
43
|
-
impactEventIds: string[];
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Derive the current state of an issue.
|
|
47
|
-
* @param bundle
|
|
48
|
-
* @returns
|
|
49
|
-
*/
|
|
50
|
-
export declare function deriveCurrentState(bundle: IssueBundle): IssueBundleState;
|
|
51
|
-
export {};
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { keyForAffectedEntity } from '#helpers/keyForAffectedEntity.js';
|
|
2
|
-
/**
|
|
3
|
-
* Derive the current state of an issue.
|
|
4
|
-
* @param bundle
|
|
5
|
-
* @returns
|
|
6
|
-
*/
|
|
7
|
-
export function deriveCurrentState(bundle) {
|
|
8
|
-
const services = {};
|
|
9
|
-
const servicesProvenance = {};
|
|
10
|
-
const facilities = {};
|
|
11
|
-
const facilitiesProvenance = {};
|
|
12
|
-
const impactEventIds = {
|
|
13
|
-
serviceEffect: null,
|
|
14
|
-
serviceScopes: null,
|
|
15
|
-
periods: null,
|
|
16
|
-
causes: null,
|
|
17
|
-
facilityEffect: null,
|
|
18
|
-
};
|
|
19
|
-
for (const impactEvent of bundle.impactEvents) {
|
|
20
|
-
const key = keyForAffectedEntity(impactEvent.entity);
|
|
21
|
-
switch (impactEvent.entity.type) {
|
|
22
|
-
case 'service': {
|
|
23
|
-
const currentState = services[key] ?? {
|
|
24
|
-
serviceId: impactEvent.entity.serviceId,
|
|
25
|
-
effect: null,
|
|
26
|
-
scopes: [],
|
|
27
|
-
periods: [],
|
|
28
|
-
causes: [],
|
|
29
|
-
};
|
|
30
|
-
const currentProvenance = servicesProvenance[key] ?? {};
|
|
31
|
-
switch (impactEvent.type) {
|
|
32
|
-
case 'service_effects.set': {
|
|
33
|
-
currentState.effect = impactEvent.effect;
|
|
34
|
-
currentProvenance.effect = {
|
|
35
|
-
evidenceId: impactEvent.basis.evidenceId,
|
|
36
|
-
};
|
|
37
|
-
impactEventIds.serviceEffect = impactEvent.id;
|
|
38
|
-
break;
|
|
39
|
-
}
|
|
40
|
-
case 'periods.set': {
|
|
41
|
-
currentState.periods = impactEvent.periods;
|
|
42
|
-
currentProvenance.periods = {
|
|
43
|
-
evidenceId: impactEvent.basis.evidenceId,
|
|
44
|
-
};
|
|
45
|
-
impactEventIds.periods = impactEvent.id;
|
|
46
|
-
break;
|
|
47
|
-
}
|
|
48
|
-
case 'service_scopes.set': {
|
|
49
|
-
currentState.scopes = impactEvent.serviceScopes;
|
|
50
|
-
currentProvenance.scopes = {
|
|
51
|
-
evidenceId: impactEvent.basis.evidenceId,
|
|
52
|
-
};
|
|
53
|
-
impactEventIds.serviceScopes = impactEvent.id;
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
case 'causes.set': {
|
|
57
|
-
currentState.causes = impactEvent.causes;
|
|
58
|
-
currentProvenance.causes = {
|
|
59
|
-
evidenceId: impactEvent.basis.evidenceId,
|
|
60
|
-
};
|
|
61
|
-
impactEventIds.causes = impactEvent.id;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
services[key] = currentState;
|
|
66
|
-
servicesProvenance[key] = currentProvenance;
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
case 'facility': {
|
|
70
|
-
const currentState = facilities[key] ?? {
|
|
71
|
-
stationId: impactEvent.entity.stationId,
|
|
72
|
-
kind: impactEvent.entity.kind,
|
|
73
|
-
effect: null,
|
|
74
|
-
periods: [],
|
|
75
|
-
};
|
|
76
|
-
const currentProvenance = facilitiesProvenance[key] ?? {};
|
|
77
|
-
switch (impactEvent.type) {
|
|
78
|
-
case 'facility_effects.set': {
|
|
79
|
-
currentState.effect = impactEvent.effect;
|
|
80
|
-
currentProvenance.effect = {
|
|
81
|
-
evidenceId: impactEvent.basis.evidenceId,
|
|
82
|
-
};
|
|
83
|
-
impactEventIds.facilityEffect = impactEvent.id;
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
case 'periods.set': {
|
|
87
|
-
currentState.periods = impactEvent.periods;
|
|
88
|
-
currentProvenance.periods = {
|
|
89
|
-
evidenceId: impactEvent.basis.evidenceId,
|
|
90
|
-
};
|
|
91
|
-
impactEventIds.periods = impactEvent.id;
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
facilities[key] = currentState;
|
|
96
|
-
facilitiesProvenance[key] = currentProvenance;
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
default: {
|
|
100
|
-
// @ts-expect-error fallback case
|
|
101
|
-
throw new Error(`Unknown entity type: ${impactEvent.entity.type}`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return {
|
|
106
|
-
services,
|
|
107
|
-
servicesProvenance,
|
|
108
|
-
facilities,
|
|
109
|
-
facilitiesProvenance,
|
|
110
|
-
impactEventIds: Object.values(impactEventIds).filter((id) => id !== null),
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
//# sourceMappingURL=deriveCurrentState.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deriveCurrentState.js","sourceRoot":"/","sources":["repo/issue/helpers/deriveCurrentState.ts"],"names":[],"mappings":"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","sourcesContent":["import { keyForAffectedEntity } from '#helpers/keyForAffectedEntity.js';\nimport type { IssueBundle } from '#schema/issue/bundle.js';\nimport type { CauseSubtype } from '#schema/issue/cause.js';\nimport type { FacilityEffect } from '#schema/issue/facilityEffect.js';\nimport type { Period } from '#schema/issue/period.js';\nimport type { ServiceEffect } from '#schema/issue/serviceEffect.js';\nimport type { ServiceScope } from '#schema/issue/serviceScope.js';\n\ntype BasisRef = {\n evidenceId: string;\n};\n\ntype ServiceProvenance = {\n effect?: BasisRef;\n scopes?: BasisRef;\n periods?: BasisRef;\n causes?: BasisRef;\n};\n\ntype ServiceState = {\n serviceId: string;\n effect: ServiceEffect | null;\n scopes: ServiceScope[];\n periods: Period[];\n causes: CauseSubtype[];\n};\n\ntype FacilityProvenance = {\n effect?: BasisRef;\n periods?: BasisRef;\n causes?: BasisRef;\n};\n\ntype FacilityState = {\n stationId: string;\n kind: 'lift' | 'escalator' | 'screen-door';\n effect: FacilityEffect | null;\n periods: Period[];\n causes: CauseSubtype[];\n};\n\nexport type IssueBundleState = {\n services: Record<string, ServiceState>;\n servicesProvenance: Record<string, ServiceProvenance>;\n facilities: Record<string, FacilityState>;\n facilitiesProvenance: Record<string, FacilityProvenance>;\n /**\n * The impact event ids that were used to derive the current state.\n */\n impactEventIds: string[];\n};\n\n/**\n * Derive the current state of an issue.\n * @param bundle\n * @returns\n */\nexport function deriveCurrentState(bundle: IssueBundle): IssueBundleState {\n const services: Record<string, ServiceState> = {};\n const servicesProvenance: Record<string, ServiceProvenance> = {};\n const facilities: Record<string, FacilityState> = {};\n const facilitiesProvenance: Record<string, FacilityProvenance> = {};\n const impactEventIds: {\n serviceEffect: string | null;\n serviceScopes: string | null;\n periods: string | null;\n causes: string | null;\n facilityEffect: string | null;\n } = {\n serviceEffect: null,\n serviceScopes: null,\n periods: null,\n causes: null,\n facilityEffect: null,\n };\n\n for (const impactEvent of bundle.impactEvents) {\n const key = keyForAffectedEntity(impactEvent.entity);\n\n switch (impactEvent.entity.type) {\n case 'service': {\n const currentState = services[key] ?? {\n serviceId: impactEvent.entity.serviceId,\n effect: null,\n scopes: [],\n periods: [],\n causes: [],\n };\n\n const currentProvenance = servicesProvenance[key] ?? {};\n\n switch (impactEvent.type) {\n case 'service_effects.set': {\n currentState.effect = impactEvent.effect;\n currentProvenance.effect = {\n evidenceId: impactEvent.basis.evidenceId,\n };\n impactEventIds.serviceEffect = impactEvent.id;\n break;\n }\n case 'periods.set': {\n currentState.periods = impactEvent.periods;\n currentProvenance.periods = {\n evidenceId: impactEvent.basis.evidenceId,\n };\n impactEventIds.periods = impactEvent.id;\n break;\n }\n case 'service_scopes.set': {\n currentState.scopes = impactEvent.serviceScopes;\n currentProvenance.scopes = {\n evidenceId: impactEvent.basis.evidenceId,\n };\n impactEventIds.serviceScopes = impactEvent.id;\n break;\n }\n case 'causes.set': {\n currentState.causes = impactEvent.causes;\n currentProvenance.causes = {\n evidenceId: impactEvent.basis.evidenceId,\n };\n impactEventIds.causes = impactEvent.id;\n break;\n }\n }\n\n services[key] = currentState;\n servicesProvenance[key] = currentProvenance;\n\n break;\n }\n case 'facility': {\n const currentState = facilities[key] ?? {\n stationId: impactEvent.entity.stationId,\n kind: impactEvent.entity.kind,\n effect: null,\n periods: [],\n };\n\n const currentProvenance = facilitiesProvenance[key] ?? {};\n\n switch (impactEvent.type) {\n case 'facility_effects.set': {\n currentState.effect = impactEvent.effect;\n currentProvenance.effect = {\n evidenceId: impactEvent.basis.evidenceId,\n };\n impactEventIds.facilityEffect = impactEvent.id;\n break;\n }\n case 'periods.set': {\n currentState.periods = impactEvent.periods;\n currentProvenance.periods = {\n evidenceId: impactEvent.basis.evidenceId,\n };\n impactEventIds.periods = impactEvent.id;\n break;\n }\n }\n\n facilities[key] = currentState;\n facilitiesProvenance[key] = currentProvenance;\n\n break;\n }\n default: {\n // @ts-expect-error fallback case\n throw new Error(`Unknown entity type: ${impactEvent.entity.type}`);\n }\n }\n }\n\n return {\n services,\n servicesProvenance,\n facilities,\n facilitiesProvenance,\n impactEventIds: Object.values(impactEventIds).filter(\n (id): id is string => id !== null,\n ),\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|