forked from pkreissel/fedialgo
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtypes.ts
More file actions
255 lines (215 loc) · 8.66 KB
/
types.ts
File metadata and controls
255 lines (215 loc) · 8.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
/*
* Typescript type definitions. Should only import types and enums.
*/
import { mastodon } from 'masto';
import { MutexInterface, SemaphoreInterface } from 'async-mutex';
import type Account from './api/objects/account';
import type BooleanFilter from './filters/boolean_filter';
import type NumericFilter from './filters/numeric_filter';
import type TagList from './api/tag_list';
import type Toot from './api/objects/toot';
import { type BooleanFilterArgs } from './filters/boolean_filter';
import { type NumericFilterArgs } from './filters/numeric_filter';
import { type SerializableToot } from './api/objects/toot';
import {
BooleanFilterName,
FediverseCacheKey,
NonScoreWeightName,
ScoreName,
TagTootsCategory,
TrendingType,
TOOT_SOURCES,
} from './enums';
// Records
export type AccountNames = Record<mastodon.v1.Account["acct"], Account>;
export type MastodonInstances = Record<string, MastodonInstance>;
export type NonScoreWeightInfoDict = Record<NonScoreWeightName, WeightInfo>;
export type ObjNames = Record<string, NamedTootCount>;
export type PromiseDict = Record<string, Promise<unknown>>;
export type StringDict = Record<string, string>;
export type StringNumberDict = Record<string, number>;
export type TagNames = Record<string, TagWithUsageCounts>;
export type WeightInfoDict = Record<WeightName, WeightInfo>;
export type Weights = Record<WeightName, number>;
// Misc
export type AccountLike = Account | mastodon.v1.Account;
export type ConcurrencyLockRelease = MutexInterface.Releaser | SemaphoreInterface.Releaser;
export type CountKey = FilterProperty | string;
export type FeedFetcher = (api: mastodon.rest.Client) => Promise<Toot[]>;
export type FilterProperty = BooleanFilterName | TootNumberProp;
export type Optional<T> = T | null | undefined;
export type OptionalNumber = Optional<number>;
export type OptionalString = Optional<string>;
export type StringSet = Set<string | undefined>;
export type TootLike = mastodon.v1.Status | SerializableToot | Toot;
export type TootNumberProp = KeysOfValueType<Toot, number>;
export type TootSource = (typeof TOOT_SOURCES)[number];
////////////////////
// Filters //
////////////////////
/** These are both both filter option property names as well as demo app gradient config keys. */
export const FILTER_OPTION_DATA_SOURCES = [
...Object.values(TagTootsCategory), // TODO: these are really the wrong cache keys for the use case but it's consistent w/demo app for now
BooleanFilterName.LANGUAGE,
ScoreName.FAVOURITED_ACCOUNTS,
] as const;
export type FilterOptionDataSource = (typeof FILTER_OPTION_DATA_SOURCES)[number];
export type BooleanFilters = Record<BooleanFilterName, BooleanFilter>;
export type NumericFilters = Record<TootNumberProp, NumericFilter>;
type FilterOptionUserData = {[key in FilterOptionDataSource]?: number};
/** Add FilterOptionDataSource properties to the {@linkcode NamedTootCount} interface. */
export interface BooleanFilterOption extends FilterOptionUserData, NamedTootCount {
isFollowed?: boolean;
};
export type FeedFilterSettingsSerialized = {
booleanFilterArgs: BooleanFilterArgs[];
numericFilterArgs: NumericFilterArgs[];
};
/**
* Represents the full set of filter settings for a feed, including both the serialized filter arguments
* and the instantiated filter objects themselves. This is used to store and manage the current state
* of all boolean and numeric filters applied to a feed, as well as the arguments needed to reconstruct them.
* @augments FeedFilterSettingsSerialized
* @property {BooleanFilters} booleanFilters - Map of boolean filter names to BooleanFilter instances.
* @property {NumericFilters} numericFilters - Map of toot number property names to NumericFilter instances.
*/
export interface FeedFilterSettings extends FeedFilterSettingsSerialized {
booleanFilters: BooleanFilters;
numericFilters: NumericFilters;
};
/**
* Utility type to extract the keys of T whose values are an extension of TypeCondition
* https://www.totaltypescript.com/get-keys-of-an-object-where-values-are-of-a-given-type
*/
export type KeysOfValueType<T, SuperClass> = Exclude<
{[K in keyof T]: T[K] extends SuperClass ? K : never}[keyof T],
undefined
>;
////////////////////////
// Mastodon API //
////////////////////////
/**
* Union type representing any object that can be returned from the Mastodon API and handled by
* the app in addition to our local extensions like {@linkcode Toot}, {@linkcode Account}, and
* {@linkcode TagWithUsageCounts}.
*/
export type ApiObj = (
ApiObjWithID |
Hashtag |
mastodon.v1.TrendLink |
string
);
/** Union type for most (but not all) Mastodon API objects with an {@linkcode id} property. */
export type ApiObjWithID = (
Account |
TootLike |
mastodon.v1.Account |
mastodon.v1.Notification |
mastodon.v1.Status |
mastodon.v2.Filter
);
/** Any CacheableApiObj will also be written to localForage with these properties. */
export interface CacheTimestamp {
isStale: boolean;
updatedAt: Date;
};
/** ApiObjs are stored in cache as arrays; MastodonInstances is our custom data structure. */
export type CacheableApiObj = (
ApiObj[]
| MastodonInstances
| mastodon.v2.Instance
);
/** Possible data sources for CountedList objects. */
export type CountedListSource = (
FilterOptionDataSource
| FilterProperty
| FediverseCacheKey.TRENDING_TAGS
| ScoreName.DIVERSITY
| ScoreName.FOLLOWED_TAGS
);
export type Hashtag = mastodon.v1.Tag | TagWithUsageCounts;
export type InstanceResponse = MastodonInstance | null;
/** Local extension to the Mastodon Instance type that adds some additional properties */
export interface MastodonInstance extends mastodon.v2.Instance {
followedPctOfMAU?: number;
MAU?: number; // MAU data is buried in the Instance hierarchy so this just a copy on the top level
};
export interface MinMax { min: number; max: number; };
export type MinMaxID = { min: string; max: string; };
export interface MinMaxAvgScore extends MinMax {
average: number;
count: number;
averageFinalScore: number;
};
/** Abstract interface for objects that have numToots of some kind. */
export interface NamedTootCount extends TootCount {
displayName?: string;
displayNameWithEmoji?: string; // TODO: just testing this
name: string;
};
export type ScoreStats = {
raw: MinMaxAvgScore[];
weighted: MinMaxAvgScore[];
};
export type ScoresStats = Record<ScoreName, ScoreStats>;
export type ScoreType = keyof WeightedScore;
/** Mastodon Tag object with additional properties for occurence counts and language. */
export interface TagWithUsageCounts extends mastodon.v1.Tag, NamedTootCount {
language?: string;
};
/** Interface for objects that contain counts of accoutns and toots. */
export interface TootCount {
numAccounts?: number;
numToots?: number;
regex?: RegExp; // TODO: this shouldn't be here
};
/** Information about a {@link Toot}'s weighted score. */
export type TootScore = {
rawScore: number; // Raw score without time decay etc. applied
score: number; // Actual final score
scores: TootScores; // All the scores for this toot
timeDecayMultiplier: number; // Multiplier that reduces the score of older posts
trendingMultiplier: number; // Multiplier applied to trending toots and tags
weightedScore: number; // Score before applying timeDecayMultiplier
};
export type TootScores = Record<ScoreName, WeightedScore>;
// TODO: "toots" is different from TrendingType.STATUSES ("statuses" is a Mastodon API type)
export type TrendingData = {
[TrendingType.LINKS]: TrendingLink[];
[TrendingType.SERVERS]: MastodonInstances;
[TrendingType.TAGS]: TagList;
toots: Toot[];
};
export interface TrendingLink extends mastodon.v1.TrendLink, TootCount {};
export type TrendingObj = Toot | TrendingWithHistory;
export type TrendingWithHistory = TagWithUsageCounts | TrendingLink;
/** Holds both the raw and unweighted score for a given {@linkcode ScoreName}. */
export type WeightedScore = {
raw: number;
weighted: number;
};
export type WeightInfo = {
description: string;
minValue?: number;
};
/** Names of all the user adjustable score weightings, both those with a Scorer and those without. */
export type WeightName = ScoreName | NonScoreWeightName;
export interface WithCreatedAt {
createdAt: string | Date; // ISO date string
};
////////////////////
// Storage //
////////////////////
/** All types that can be written to storage. */
export type StorableObj = (
CacheableApiObj
| FeedFilterSettingsSerialized
| ApiObj
| StringNumberDict
| Weights
| number
);
export type StorableWithTimestamp = {
updatedAt: string;
value: StorableObj;
};