Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔀♻️⚡️ rewrite api-store #2921

Merged
merged 74 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
f1da374
🚧 [workers] add a TypedWorker class for shared workers
jxn-30 Feb 8, 2024
095f14b
🚧 [workers] experiment with workers
jxn-30 Feb 9, 2024
e01a9b1
🚧 [workers] create a working typed API-fetch worker
jxn-30 Feb 9, 2024
b1e2994
🚧 [workers] vehicles API can be stored and fetched
jxn-30 Feb 10, 2024
d3c7050
🚧 [workers] add a worker to compute vehicles fake-computeds
jxn-30 Feb 10, 2024
4545d90
🚧 [rewriteApiStore] update vehicles from radioMessage
jxn-30 Feb 11, 2024
2efc06d
🚧 [rewriteApiStore] add fetching buildings API
jxn-30 Feb 11, 2024
c8f4b72
🚧 [rewriteApiStore] add updating building on buildingMarkerAdd
jxn-30 Feb 15, 2024
06994b4
🚧 [rewriteApiStore] add fetching a single vehicle
jxn-30 Feb 16, 2024
8327518
🚧 [rewriteApiStore] add fetching a single building
jxn-30 Feb 16, 2024
06bc06a
🚧 [rewriteApiStore] add missions
jxn-30 Feb 17, 2024
4e74956
🚧 [rewriteApiStore] migrate missions to new store
jxn-30 Feb 17, 2024
4cb2021
🚧 [rewriteApiStore] add participatedMissions
jxn-30 Feb 18, 2024
07e10ac
Merge branch 'dev' into rewrite-apistore
jxn-30 Feb 24, 2024
7a774cd
🚧 [rewriteApiStore] rename missionTypesArray getter
jxn-30 Feb 24, 2024
2962651
🚧 [rewriteApiStore] store missions in a new indexedDB
jxn-30 Feb 25, 2024
4d2ce5f
🚧 [rewriteApiStore] add allianceinfo API endpoint
jxn-30 Feb 25, 2024
537c9f0
🚧 [rewriteApiStore] autoupdate
jxn-30 Feb 25, 2024
89253c8
🚧 [rewriteApiStore] add credits API
jxn-30 Feb 25, 2024
17adf8b
🚧 [rewriteApiStore] fix congruent requests to same worker
jxn-30 Feb 25, 2024
bce034b
🚧 [rewriteApiStore] fix worker param passing
jxn-30 Feb 25, 2024
221e1c1
🚧 [rewriteApiStore] store api results in worker for caching purposes
jxn-30 Feb 25, 2024
599897b
🚧 [rewriteApiStore] remove missions from broadcast
jxn-30 Feb 25, 2024
fbb508e
🚧 [rewriteApiStore] add settings API
jxn-30 Feb 25, 2024
60e52a9
🚧 [rewriteAPIStore] migrate request method
jxn-30 Feb 26, 2024
02564df
🚧 [rewriteAPIStore] make telemetry await fetching secret key
jxn-30 Feb 26, 2024
3cad9da
Merge branch 'dev' into rewrite-apistore
jxn-30 Feb 27, 2024
c741cea
🐛 [telemetry] fix getting secret key
jxn-30 Feb 27, 2024
451bbe5
🚧 [rewriteAPIStore] add schoolings and alliance_schoolings
jxn-30 Feb 28, 2024
b67b4b1
🚧 [rewriteApiStore] do not require missionTypes to be stored to resol…
jxn-30 Feb 28, 2024
146060b
🐛 [config] fix accidental change of server URL
jxn-30 Feb 28, 2024
8a9b004
♻️ [LSSMStorage] prevent DB upgrade bugs
jxn-30 Feb 28, 2024
06dc104
🚧 [rewriteApiStore] fetch vehicles at building
jxn-30 Feb 28, 2024
d4cf235
🚧 [rewriteApiStore] migrate vehicles
jxn-30 Feb 28, 2024
e9ed3d9
🐛 [dashboard] fix vehiclesByBuilding not being used correctly
jxn-30 Feb 28, 2024
97bb387
Merge branch 'dev' into rewrite-apistore
jxn-30 Feb 29, 2024
add0c3a
🐛 [dashboard] fix vehicleTypes
jxn-30 Feb 29, 2024
2fb166c
🐛 [dashboard] fix calculating water and foam
jxn-30 Feb 29, 2024
c1af508
🐛 [dashboard] fix vehicle charts
jxn-30 Feb 29, 2024
c8bc5ab
Merge branch 'dev' into rewrite-apistore
jxn-30 Feb 29, 2024
5df4866
Merge branch 'dev' into rewrite-apistore
jxn-30 Feb 29, 2024
9bf7422
🐛 [heatmap] fix heatmap settings not loading
jxn-30 Feb 29, 2024
9e262c0
🚧 [rewriteAPIStore] add alliance_buildings (no migration yet)
jxn-30 Feb 29, 2024
60d562a
♻️ [TypedWorkers] improve types of TypedWorker class and instances
jxn-30 Mar 1, 2024
f000eed
♻️ [TypedWorkers] add importableScript to check for LSSM-Header in init
jxn-30 Mar 1, 2024
813efe0
♻️ [TypedWorkers] add names of imported scripts as comments
jxn-30 Mar 1, 2024
02d48ac
♻️ [TypedWorkers] add names of typed workers as comments
jxn-30 Mar 1, 2024
1817c17
Merge branch 'dev' into rewrite-apistore
jxn-30 Mar 1, 2024
5f10fc6
♻️ [api] remove unused features from old API-Store
jxn-30 Mar 1, 2024
4e0b37d
🚧 [rewriteAPIStore] migrate alliance_buildings
jxn-30 Mar 1, 2024
e014e9e
♻️ [TypedWorker] allow more flexible imports
jxn-30 Mar 1, 2024
b26d232
🚧 [rewriteAPIStore] adjust building type for small buildings
jxn-30 Mar 1, 2024
6bcd51a
♻️ [TypedWorker] improve what's importable
jxn-30 Mar 1, 2024
26483cd
🚧 [rewriteAPIStore] migrate buildings
jxn-30 Mar 1, 2024
c982a80
🔥 [rewriteAPIStore] remove old API-Store file
jxn-30 Mar 1, 2024
9a81e66
🐛 [buildingComplex] fix some calls of new API store
jxn-30 Mar 2, 2024
d139113
✨⚡ rewrite API Store (remove `new` from name)
jxn-30 Mar 2, 2024
dca0030
Merge branch 'dev' into rewrite-apistore
jxn-30 Mar 2, 2024
d451604
⚡ [api] do not update vehiclesByDispatchCenter after buildings update…
jxn-30 Mar 2, 2024
305d1fd
⚡ [api] use references for fake computed values
jxn-30 Mar 5, 2024
844a750
Merge branch 'dev' into rewrite-apistore
jxn-30 Mar 5, 2024
2d0193b
⚡ [api] improve updating vehicles
jxn-30 Mar 6, 2024
f3a8351
⚡ [api] improve updating buildings
jxn-30 Mar 6, 2024
849f8a3
♻️ [api] remove lastUpdates from exported state
jxn-30 Mar 6, 2024
b1f1230
Merge branch 'dev' into rewrite-apistore
jxn-30 Mar 6, 2024
806f919
Merge branch 'dev' into rewrite-apistore
jxn-30 Mar 6, 2024
552d16e
Merge branch 'dev' into rewrite-apistore
jxn-30 Mar 7, 2024
636c32e
👽 [types] add tractive_random to vehicle types
jxn-30 Mar 7, 2024
f235850
♻️ [fetchApi] move postprocessing API fetch to a const
jxn-30 Mar 8, 2024
02e2f7d
🔥 [lssmaql] disable module as broken with API-Store rewrite
jxn-30 Mar 8, 2024
7a26a0f
🐛 [docs] remove disabled lssmaql from v3Comparison
jxn-30 Mar 8, 2024
ae7912a
♻️ [TypedWorker] log errors in console
jxn-30 Mar 8, 2024
dc78728
Merge branch 'dev' into rewrite-apistore
jxn-30 Mar 8, 2024
5fdc22a
Merge branch 'dev' into rewrite-apistore
jxn-30 Mar 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/.vuepress/utils/v3Comparison.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
"chatExtras",
"enhancedPOI",
"generalExtensions",
"lssmaql",
"messageTemplates",
"schoolingOverview"
]
Expand Down
8 changes: 4 additions & 4 deletions src/components/LoadingIndicator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ onMounted(() => {
// if there are no file-sizes cached, fetch them
if (Object.values(fileSizes.value).length === 0) {
useAPIStore()
.request({
url: rootStore.lssmUrl('/static/fileSizes.json', true),
feature: 'loading-indicator',
})
.request(
rootStore.lssmUrl('/static/fileSizes.json', true),
'loading-indicator'
)
.then(res => res.json())
.then(sizes => {
fileSizes.value = sizes;
Expand Down
5 changes: 1 addition & 4 deletions src/components/settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -848,10 +848,7 @@ export default Vue.extend<
(window[PREFIX] as Vue).$settings = this;

useAPIStore()
.request({
url: this.rootStore.lssmUrl('/branches.json'),
feature: 'settings',
})
.request(this.rootStore.lssmUrl('/branches.json'), 'settings')
.then(res => res.json() as Promise<SettingsData['branches']>)
.then(branches => (this.branches = branches));
},
Expand Down
2 changes: 0 additions & 2 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ utils(Vue);

const locale = LSSM.$stores.root.locale;

LSSM.$stores.api._initAPIsFromBroadcast().then();

import('./natives/checkboxMultiSelect').then(({ default: multiSelect }) =>
multiSelect(LSSM)
);
Expand Down
108 changes: 108 additions & 0 deletions src/importableScripts/LSSMStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import type { Mission } from 'typings/Mission';
import type { MissionsById } from '@workers/stores/api/missionTypes.worker';

export default class LSSMStorage {
readonly #DB_NAME = `${PREFIX}-storage-v2`;

#db: IDBDatabase | null = null;

async #upgradeDB({ oldVersion }: IDBVersionChangeEvent) {
if (!this.#db) return;

const transactions: Promise<void>[] = [];

const addTransaction = (transaction: IDBTransaction) =>
transactions.push(
new Promise<void>(resolve =>
transaction.addEventListener('complete', () => resolve())
)
);

// In version 1, we introduced storing missionTypes
if (oldVersion < 1) {
addTransaction(
this.#db.createObjectStore('missionTypes', { keyPath: 'id' })
.transaction
);
}

await Promise.all(transactions);
}

#setDB(db: IDBDatabase) {
if (this.#db) return;
this.#db = db;
}

#openDB() {
if (this.#db) return Promise.resolve(this.#db);
return new Promise<IDBDatabase>((resolve, reject) => {
const request = indexedDB.open(this.#DB_NAME, 1);

let upgradeNeeded = false;

request.addEventListener('success', () => {
if (upgradeNeeded) return;
this.#setDB(request.result);
return resolve(request.result);
});
request.addEventListener('error', () => reject(request.error));

request.addEventListener('upgradeneeded', async event => {
upgradeNeeded = true;
this.#setDB(request.result);
await this.#upgradeDB(event);
return resolve(request.result);
});
});
}

#closeDB() {
if (this.#db) this.#db.close();
this.#db = null;
}

// region missionTypes
public storeMissionTypes(missionTypes: MissionsById) {
return this.#openDB()
.then(db => {
const tx = db.transaction('missionTypes', 'readwrite');
const store = tx.objectStore('missionTypes');
Object.values(missionTypes).forEach(missionType => {
store.put(missionType);
});
return new Promise<void>((resolve, reject) => {
tx.addEventListener('complete', () => resolve());
tx.addEventListener('error', () => reject(tx.error));
});
})
.finally(() => this.#closeDB());
}

public getMissionTypes() {
return this.#openDB()
.then(db => {
const tx = db.transaction('missionTypes', 'readonly');
const store = tx.objectStore('missionTypes');
const request = store.getAll();
return new Promise<Mission[]>((resolve, reject) => {
request.addEventListener('success', () =>
resolve(request.result)
);
request.addEventListener('error', () =>
reject(request.error)
);
});
})
.then(missionTypes => {
// indexedDB returns an array, so we need to convert it to an object
const missionTypesObject: MissionsById = {};
missionTypes.forEach(missionType => {
missionTypesObject[missionType.id] = missionType;
});
return missionTypesObject;
})
.finally(() => this.#closeDB());
}
// endregion
}
16 changes: 16 additions & 0 deletions src/importableScripts/checkRequestInit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Checks if the RequestInit has the LSSM-Header set and throws an error if not.
* @param init - The RequestInit to check against.
* @throws Error If the LSSM-Header is not set.
*/
export default (init: RequestInit) => {
const headers = new Headers(init.headers);

// CAVEAT: headers are stored lowercase
// if the LSSM-Header is not set, abort the request!
if (!headers.has('x-lss-manager')) {
throw new Error(
'No X-LSS-Manager Header has been set. Aborting the request!'
);
}
};
59 changes: 17 additions & 42 deletions src/mainpageCore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import he from 'he';

import loadingIndicatorStorageKey from '../build/plugins/LoadingProgressPluginStorageKey';
import LSSMMenu from './LSSM-Menu.vue';
import telemetry from './modules/telemetry/main';
Expand Down Expand Up @@ -115,7 +113,7 @@ export default async (LSSM: Vue): Promise<void> => {
control.style.setProperty('cursor', 'pointer');
LSSM.$stores.api
.getSettings('mainPage-core_map-expand')
.then(({ value: { design_mode } }) =>
.then(({ design_mode }) =>
control.addEventListener('click', () => {
window.mapExpand(design_mode >= 3);
})
Expand All @@ -142,51 +140,28 @@ export default async (LSSM: Vue): Promise<void> => {
event: 'radioMessage',
post: false,
callback(radioMessage: RadioMessage) {
if (
radioMessage.type === 'vehicle_fms' &&
radioMessage.user_id === window.user_id
)
LSSM.$stores.api.radioMessage(radioMessage);
LSSM.$stores.api.updateVehicleFromRadioMessage(radioMessage);
Cr4zyc4k3 marked this conversation as resolved.
Show resolved Hide resolved
},
});

await LSSM.$stores.api.getBuildings('mainPage-core_initial-update');
await LSSM.$stores.api.getMissions('mainPage-core_initial-update', true);
LSSM.$stores.api.getBuildings('mainPage-core_initial-update').then();

LSSM.$stores.root.hook({
event: 'buildingMarkerAdd',
callback(buildingMarker: BuildingMarkerAdd) {
if (buildingMarker.user_id !== window.user_id) return;
const buildings = LSSM.$stores.api.buildings;
const building = buildings.find(
({ id }) => id === buildingMarker.id
);
if (
!building ||
building.caption !== he.decode(buildingMarker.name)
) {
LSSM.$stores.api
.getBuilding(
buildingMarker.id,
'mainPage-core_buildingMarkerAdd'
)
.then(building =>
LSSM.$stores.api
.getVehiclesAtBuilding(
building.id,
'mainPage-core_buildingMarkerAdd'
)
.then(() =>
LSSM.$stores.event.createAndDispatchEvent({
name: 'buildingMarkerAdd',
detail: {
marker: buildingMarker,
building,
},
})
)
);
}
async callback(buildingMarker: BuildingMarkerAdd) {
const building =
await LSSM.$stores.api.updateBuildingFromBuildingMarkerAdd(
buildingMarker
);

if (!building) return;
LSSM.$stores.event.createAndDispatchEvent({
name: 'buildingMarkerAdd',
detail: {
marker: buildingMarker,
building,
},
});
},
});
};
26 changes: 11 additions & 15 deletions src/modules/asyncButtons/assets/arr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,18 @@ export default (LSSM: Vue, $m: $m, MODULE_ID: string): void => {
?.getAttribute('content') || ''
);
await LSSM.$stores.api
.request({
url: btn.href,
init: {
method: 'POST',
body: url.searchParams.toString(),
credentials: 'include',
mode: 'cors',
headers: {
'Accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Content-Type':
'application/x-www-form-urlencoded',
'Upgrade-Insecure-Requests': '1',
},
.request(btn.href, `${MODULE_ID}-arr`, {
method: 'POST',
body: url.searchParams.toString(),
credentials: 'include',
mode: 'cors',
headers: {
'Accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Content-Type':
'application/x-www-form-urlencoded',
'Upgrade-Insecure-Requests': '1',
},
feature: `${MODULE_ID}-arr`,
})
.then(({ status }) => {
if (status !== 200) return;
Expand Down
12 changes: 6 additions & 6 deletions src/modules/asyncButtons/assets/buildingPersonal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ export default (LSSM: Vue, $m: $m, MODULE_ID: string): void => {
?.getAttribute('content') || ''
);
await LSSM.$stores.api
.request({
url: btn.href,
init: {
.request(
btn.href,
`${MODULE_ID}-buildingPersonal`,
{
method: 'POST',
body: url.searchParams.toString(),
credentials: 'include',
Expand All @@ -50,9 +51,8 @@ export default (LSSM: Vue, $m: $m, MODULE_ID: string): void => {
'application/x-www-form-urlencoded',
'Upgrade-Insecure-Requests': '1',
},
},
feature: `${MODULE_ID}-buildingPersonal`,
})
}
)
.then(({ status }) => {
if (status !== 200) return;
btn.parentElement?.parentElement?.parentElement?.classList.add(
Expand Down
20 changes: 10 additions & 10 deletions src/modules/asyncButtons/assets/buildings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ export default (
e.preventDefault();
taxBtns.forEach(taxBtn => taxBtn.classList.add('disabled'));
await LSSM.$stores.api
.request({
url: btn.getAttribute('href') ?? '',
feature: `${MODULE_ID}-buildings`,
})
.request(
btn.getAttribute('href') ?? '',
`${MODULE_ID}-buildings`
)
.then(({ status }) => {
if (status === 200) {
document
Expand Down Expand Up @@ -72,9 +72,10 @@ export default (
?.getAttribute('content') || ''
);
await LSSM.$stores.api
.request({
url: btn.getAttribute('href') ?? '',
init: {
.request(
btn.getAttribute('href') ?? '',
'ab-buildings-extensionState',
{
method: 'POST',
body: url.searchParams.toString(),
headers: {
Expand All @@ -84,9 +85,8 @@ export default (
'application/x-www-form-urlencoded',
'Upgrade-Insecure-Requests': '1',
},
},
feature: 'ab-buildings-extensionState',
})
}
)
.then(({ status }) => {
if (status === 200) {
extensionStateBtns.forEach(tbtn =>
Expand Down
22 changes: 9 additions & 13 deletions src/modules/asyncButtons/assets/forumpost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,16 @@ export default (LSSM: Vue, $m: $m, MODULE_ID: string): void => {
?.getAttribute('content') || ''
);
await LSSM.$stores.api
.request({
url: btn.href,
init: {
method: 'POST',
body: url.searchParams.toString(),
credentials: 'include',
mode: 'cors',
headers: {
'content-type':
'application/x-www-form-urlencoded',
'upgrade-insecure-requests': '1',
},
.request(btn.href, `${MODULE_ID}-forumpost`, {
method: 'POST',
body: url.searchParams.toString(),
credentials: 'include',
mode: 'cors',
headers: {
'content-type':
'application/x-www-form-urlencoded',
'upgrade-insecure-requests': '1',
},
feature: `${MODULE_ID}-forumpost`,
})
.then(({ status }) => {
if (status !== 200) return;
Expand Down
5 changes: 1 addition & 4 deletions src/modules/asyncButtons/assets/memberlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ export default (LSSM: Vue, $m: $m, MODULE_ID: string): void => {
t: HTMLAnchorElement
) => {
await LSSM.$stores.api
.request({
url: t.getAttribute('href') ?? '',
feature: `${MODULE_ID}-memberlist`,
})
.request(t.getAttribute('href') ?? '', `${MODULE_ID}-memberlist`)
.then(({ status }) => {
if (status !== 200) return;
const href = t.getAttribute('href')?.split('/');
Expand Down
Loading