diff --git a/app/scripts/backend/backend.ts b/app/scripts/backend/backend.ts index e219d8a4..3f233391 100644 --- a/app/scripts/backend/backend.ts +++ b/app/scripts/backend/backend.ts @@ -5,20 +5,9 @@ import { KorpResponse, WithinParameters } from "@/backend/types" import { SavedSearch } from "@/local-storage" import settings from "@/settings" import { httpConfAddMethodFetch } from "@/util" -import { KorpStatsResponse, normalizeStatsData } from "@/backend/stats-proxy" +import { normalizeStatsData } from "@/backend/stats-proxy" import { MapResult, parseMapData } from "@/map_services" -import { KorpQueryResponse } from "@/backend/kwic-proxy" - -type KorpLoglikeResponse = { - /** Log-likelihood average. */ - average: number - /** Log-likelihood values. */ - loglike: Record - /** Absolute frequency for the values in set 1. */ - set1: Record - /** Absolute frequency for the values in set 2. */ - set2: Record -} +import { count, loglike, QueryResponse } from "./client" export type CompareResult = [CompareTables, number, SavedSearch, SavedSearch, string[]] @@ -80,7 +69,7 @@ export async function requestCompare( const rankedReduce = _.filter(reduce, (item) => cl.getCurrentAttributes(cl.getReduceLang())[item]?.ranked) const top = rankedReduce.map((item) => item + ":1").join(",") - const params = { + const data = await loglike({ group_by: reduce.join(","), set1_corpus: corpora1.join(",").toUpperCase(), set1_cqp: cmpObj1.cqp, @@ -89,9 +78,7 @@ export async function requestCompare( max: "50", split, top, - } - - const data = await korpRequest("loglike", params) + }) if ("ERROR" in data) { // TODO Create a KorpBackendError which could be displayed nicely @@ -137,19 +124,16 @@ export async function requestMapData( const cqpSubExprs = {} _.map(_.keys(cqpExprs), (subCqp, idx) => (cqpSubExprs[`subcqp${idx}`] = subCqp)) - const params = { + const data = await count({ group_by_struct: attribute.label, cqp, corpus: attribute.corpora.join(","), incremental: true, split: attribute.label, relative_to_struct: relative ? attribute.label : undefined, - } - _.extend(params, settings.corpusListing.getWithinParameters()) - - _.extend(params, cqpSubExprs) - - const data = await korpRequest("count", params) + ...settings.corpusListing.getWithinParameters(), + ...cqpSubExprs, + }) if ("ERROR" in data) { // TODO Create a KorpBackendError which could be displayed nicely @@ -161,10 +145,7 @@ export async function requestMapData( return { corpora: attribute.corpora, cqp, within, data: result, attribute } } -export async function getDataForReadingMode( - inputCorpus: string, - textId: string -): Promise> { +export async function getDataForReadingMode(inputCorpus: string, textId: string): Promise> { const corpus = inputCorpus.toUpperCase() const corpusSettings = settings.corpusListing.get(inputCorpus) @@ -187,5 +168,5 @@ export async function getDataForReadingMode( end: 0, } - return korpRequest("query", params) + return korpRequest("query", params) } diff --git a/app/scripts/backend/client.ts b/app/scripts/backend/client.ts new file mode 100644 index 00000000..618542a9 --- /dev/null +++ b/app/scripts/backend/client.ts @@ -0,0 +1,123 @@ +/** @format */ + +import { getAuthorizationHeader } from "@/components/auth/auth" +import { httpConfAddMethodFetch } from "@/util" +import { ApiKwic, KorpResponse, StatsColumn } from "@/backend/types" +import settings from "@/settings" + +async function korpRequest = {}, P extends Record = {}>( + endpoint: string, + params: P +): Promise> { + const { url, request } = httpConfAddMethodFetch(settings.korp_backend_url + "/" + endpoint, params) + request.headers = { ...request.headers, ...getAuthorizationHeader() } + const response = await fetch(url, request) + return (await response.json()) as KorpResponse +} + +/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Misc/paths/~1loglike/get */ +export type LoglikeResponse = { + /** Log-likelihood average. */ + average: number + /** Log-likelihood values. */ + loglike: Record + /** Absolute frequency for the values in set 1. */ + set1: Record + /** Absolute frequency for the values in set 2. */ + set2: Record +} + +/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Misc/paths/~1loglike/get */ +export type LoglikeParams = { + group_by: string + set1_corpus: string + set1_cqp: string + set2_corpus: string + set2_cqp: string + max: `${number}` + split: string + top: string +} + +export const loglike = (params: LoglikeParams) => korpRequest("loglike", params) + +/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Statistics/paths/~1count/get */ +export type CountParams = { + /** Corpus names, separated by comma */ + corpus: string + /** CQP query */ + cqp: string + /** Positional attribute by which the hits should be grouped. Defaults to "word" if neither `group_by` nor `group_by_struct` is defined */ + group_by?: string + /** Structural attribute by which the hits should be grouped. The value for the first token of the hit will be used */ + group_by_struct?: string + /** Prevent search from crossing boundaries of the given structural attribute, e.g. 'sentence'. */ + default_within?: string + /** Like default_within, but for specific corpora, overriding the default. Specified using the format 'corpus:attribute' */ + within?: string + ignore_case?: string + relative_to_struct?: string + split?: string + top?: string + [cqpn: `cqp${number}`]: string + expand_prequeries?: boolean + [subcqpn: `subcqp${number}`]: string + start?: number + end?: number + /** Incrementally return progress updates when the calculation for each corpus is finished */ + incremental?: boolean +} + +/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Statistics/paths/~1count/get */ +export type CountResponse = { + corpora: { + [name: string]: StatsColumn | StatsColumn[] + } + combined: StatsColumn | StatsColumn[] + /** Total number of different values */ + count: number + /** Execution time in seconds */ + time: number +} + +export const count = (params: CountParams) => korpRequest("count", params) + +/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Concordance/paths/~1query/get */ +export type QueryParams = { + corpus: string + cqp: string + start?: number + end?: number + default_context?: string + context?: string + show?: string + show_struct?: string + default_within?: string + within?: string + in_order?: boolean + sort?: string + random_seed?: number + cut?: number + [cqpn: `cqp${number}`]: string + expand_prequeries?: boolean + incremental?: boolean + query_data?: string +} + +/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Concordance/paths/~1query/get */ +export type QueryResponse = { + /** Search hits */ + kwic: ApiKwic[] + /** Total number of hits */ + hits: number + /** Number of hits for each corpus */ + corpus_hits: Record + /** Order of corpora in result */ + corpus_order: string[] + /** Execution time in seconds */ + time: number + /** A hash of this query */ + query_data: string +} + +export const query = (params: QueryParams) => korpRequest("query", params) diff --git a/app/scripts/backend/graph-proxy.ts b/app/scripts/backend/graph-proxy.ts index 51452367..b3c5a87f 100644 --- a/app/scripts/backend/graph-proxy.ts +++ b/app/scripts/backend/graph-proxy.ts @@ -2,8 +2,7 @@ import _ from "lodash" import settings from "@/settings" import BaseProxy from "@/backend/base-proxy" -import { AjaxSettings, Granularity, Histogram, KorpResponse, NumericString } from "@/backend/types" -import { AbsRelTuple } from "@/statistics.types" +import { AbsRelTuple, AjaxSettings, Granularity, Histogram, KorpResponse, NumericString } from "@/backend/types" import { Factory, httpConfAddMethod } from "@/util" export class GraphProxy extends BaseProxy { diff --git a/app/scripts/backend/kwic-proxy.ts b/app/scripts/backend/kwic-proxy.ts index ce5de3a7..918a48fd 100644 --- a/app/scripts/backend/kwic-proxy.ts +++ b/app/scripts/backend/kwic-proxy.ts @@ -2,13 +2,14 @@ import _ from "lodash" import settings from "@/settings" import BaseProxy from "@/backend/base-proxy" -import type { AjaxSettings, KorpResponse, ProgressReport, ProgressResponse } from "@/backend/types" +import type { AjaxSettings, KorpResponse, ProgressReport } from "@/backend/types" import { locationSearchGet, httpConfAddMethod, Factory } from "@/util" +import { QueryParams, QueryResponse } from "./client" -export class KwicProxy extends BaseProxy { +export class KwicProxy extends BaseProxy { foundKwic: boolean prevCQP?: string - prevParams: KorpQueryParams | null + prevParams: QueryParams | null prevRequest: JQuery.AjaxSettings | null prevUrl?: string queryData?: string @@ -24,9 +25,9 @@ export class KwicProxy extends BaseProxy { makeRequest( options: KorpQueryRequestOptions, page: number | undefined, - progressCallback: (data: ProgressReport) => void, - kwicCallback: (data: KorpResponse) => void - ): JQuery.jqXHR> { + progressCallback: (data: ProgressReport) => void, + kwicCallback: (data: KorpResponse) => void + ): JQuery.jqXHR> { const self = this this.foundKwic = false this.resetRequest() @@ -49,7 +50,7 @@ export class KwicProxy extends BaseProxy { const command = options.ajaxParams.command || "query" - const data: KorpQueryParams = { + const data: QueryParams = { default_context: settings.default_overview_context, ...getPageInterval(), ...options.ajaxParams, @@ -103,7 +104,7 @@ export class KwicProxy extends BaseProxy { self.prevUrl = self.makeUrlWithParams(this.url, data) }, - success(data: KorpQueryResponse, status, jqxhr) { + success(data: QueryResponse, status, jqxhr) { self.queryData = data.query_data self.cleanup() // TODO Should be `options.ajaxParams.incremental`? @@ -119,12 +120,12 @@ export class KwicProxy extends BaseProxy { progressCallback(progressObj) if ("kwic" in progressObj.struct) { this.foundKwic = true - return kwicCallback(progressObj.struct as KorpQueryResponse) + return kwicCallback(progressObj.struct as QueryResponse) } }, } - const def = $.ajax(httpConfAddMethod(ajaxSettings)) as JQuery.jqXHR> + const def = $.ajax(httpConfAddMethod(ajaxSettings)) as JQuery.jqXHR> this.pendingRequests.push(def) return def } @@ -133,84 +134,13 @@ export class KwicProxy extends BaseProxy { const kwicProxyFactory = new Factory(KwicProxy) export default kwicProxyFactory -/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Concordance/paths/~1query/get */ -export type KorpQueryParams = { - corpus: string - cqp: string - start?: number - end?: number - default_context?: string - context?: string - show?: string - show_struct?: string - default_within?: string - within?: string - in_order?: boolean - sort?: string - random_seed?: number - cut?: number - [cqpn: `cqp${number}`]: string - expand_prequeries?: boolean - incremental?: boolean - query_data?: string -} - export type KorpQueryRequestOptions = { // TODO Should start,end really exist here as well as under ajaxParams? start?: number end?: number - ajaxParams: KorpQueryParams & { + ajaxParams: QueryParams & { command?: string } } type Interval = { start: number; end: number } - -/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Concordance/paths/~1query/get */ -export type KorpQueryResponse = { - /** Search hits */ - kwic: ApiKwic[] - /** Total number of hits */ - hits: number - /** Number of hits for each corpus */ - corpus_hits: Record - /** Order of corpora in result */ - corpus_order: string[] - /** Execution time in seconds */ - time: number - /** A hash of this query */ - query_data: string -} - -/** Search hits */ -export type ApiKwic = { - /** An object for each token in the context, with attribute values for that token */ - tokens: Token[] - /** Attribute values for the context (e.g. sentence) */ - structs: Record - /** Specifies the position of the match in the context. If `in_order` is false, `match` will consist of a list of match objects, one per highlighted word */ - match: KwicMatch | KwicMatch[] - /** Hits from aligned corpora if available, otherwise omitted */ - aligned: { - [linkedCorpusId: `${string}-${string}`]: Record[] - } -} - -/** Specifies the position of a match in a context */ -type KwicMatch = { - /** Start position of the match within the context */ - start: number - /** End position of the match within the context */ - end: number - /** Global corpus position of the match */ - position: number -} - -export type Token = { - word: string - structs?: { - open?: Record>[] - close?: string[] - } - [attr: string]: any -} diff --git a/app/scripts/backend/stats-proxy.ts b/app/scripts/backend/stats-proxy.ts index 6cf84f59..a2306a20 100644 --- a/app/scripts/backend/stats-proxy.ts +++ b/app/scripts/backend/stats-proxy.ts @@ -2,17 +2,18 @@ import _ from "lodash" import settings from "@/settings" import BaseProxy from "@/backend/base-proxy" -import type { AjaxSettings, KorpResponse, ProgressResponse, ProgressReport } from "@/backend/types" -import { StatsNormalized, StatsColumn, StatisticsWorkerResult } from "@/statistics.types" +import type { AjaxSettings, KorpResponse, ProgressResponse, ProgressReport, StatsColumn } from "@/backend/types" +import { StatsNormalized, StatisticsWorkerResult } from "@/statistics.types" import { locationSearchGet, httpConfAddMethod, Factory } from "@/util" import { statisticsService } from "@/statistics" +import { CountParams, CountResponse } from "./client" /** * Stats in the response can be split by subqueries if the `subcqp#` param is used, but otherwise not. * * This function adds a split (converts non-arrays to single-element arrays) if not, so higher code can assume the same shape regardless. */ -export function normalizeStatsData(data: KorpStatsResponse): StatsNormalized { +export function normalizeStatsData(data: CountResponse): StatsNormalized { const combined = !Array.isArray(data.combined) ? [data.combined] : data.combined const corpora: Record = {} @@ -25,8 +26,8 @@ export function normalizeStatsData(data: KorpStatsResponse): StatsNormalized { return { ...data, combined, corpora } } -export class StatsProxy extends BaseProxy { - prevParams: KorpStatsParams | null +export class StatsProxy extends BaseProxy { + prevParams: CountParams | null prevRequest: AjaxSettings | null prevUrl?: string @@ -36,7 +37,7 @@ export class StatsProxy extends BaseProxy { this.prevParams = null } - makeParameters(reduceVals: string[], cqp: string, ignoreCase: boolean): KorpStatsParams { + makeParameters(reduceVals: string[], cqp: string, ignoreCase: boolean): CountParams { const structAttrs = settings.corpusListing.getStructAttrs(settings.corpusListing.getReduceLang()) const groupBy: string[] = [] const groupByStruct: string[] = [] @@ -66,7 +67,7 @@ export class StatsProxy extends BaseProxy { makeRequest( cqp: string, - callback: (data: ProgressReport) => void + callback: (data: ProgressReport) => void ): JQuery.Promise { const self = this this.resetRequest() @@ -113,7 +114,7 @@ export class StatsProxy extends BaseProxy { const def: JQuery.Deferred = $.Deferred() const url = settings.korp_backend_url + "/count" - const ajaxSettings: AjaxSettings> = { + const ajaxSettings: AjaxSettings> = { url, data, beforeSend(req, settings) { @@ -137,7 +138,7 @@ export class StatsProxy extends BaseProxy { } }, - success: (data: KorpResponse) => { + success: (data: KorpResponse) => { self.cleanup() if ("ERROR" in data) { console.log("gettings stats failed with error", data.ERROR) @@ -156,7 +157,7 @@ export class StatsProxy extends BaseProxy { ) }, } - this.pendingRequests.push($.ajax(httpConfAddMethod(ajaxSettings)) as JQuery.jqXHR) + this.pendingRequests.push($.ajax(httpConfAddMethod(ajaxSettings)) as JQuery.jqXHR) return def.promise() } @@ -164,42 +165,3 @@ export class StatsProxy extends BaseProxy { const statsProxyFactory = new Factory(StatsProxy) export default statsProxyFactory - -/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Statistics/paths/~1count/get */ -type KorpStatsParams = { - /** Corpus names, separated by comma */ - corpus: string - /** CQP query */ - cqp: string - /** Positional attribute by which the hits should be grouped. Defaults to "word" if neither `group_by` nor `group_by_struct` is defined */ - group_by?: string - /** Structural attribute by which the hits should be grouped. The value for the first token of the hit will be used */ - group_by_struct?: string - /** Prevent search from crossing boundaries of the given structural attribute, e.g. 'sentence'. */ - default_within?: string - /** Like default_within, but for specific corpora, overriding the default. Specified using the format 'corpus:attribute' */ - within?: string - ignore_case?: string - relative_to_struct?: string - split?: string - top?: string - [cqpn: `cqp${number}`]: string - expand_prequeries?: boolean - [subcqpn: `subcqp${number}`]: string - start?: number - end?: number - /** Incrementally return progress updates when the calculation for each corpus is finished */ - incremental?: boolean -} - -/** @see https://ws.spraakbanken.gu.se/docs/korp#tag/Statistics/paths/~1count/get */ -export type KorpStatsResponse = { - corpora: { - [name: string]: StatsColumn | StatsColumn[] - } - combined: StatsColumn | StatsColumn[] - /** Total number of different values */ - count: number - /** Execution time in seconds */ - time: number -} diff --git a/app/scripts/backend/types.ts b/app/scripts/backend/types.ts index 83366207..d9d688ad 100644 --- a/app/scripts/backend/types.ts +++ b/app/scripts/backend/types.ts @@ -63,3 +63,48 @@ export type WithinParameters = { default_within: string within: string } + +export type StatsColumn = { + sums: AbsRelTuple + rows: StatsRow[] +} + +/** Frequency count as absolute and relative (to some total size). */ +export type AbsRelTuple = { absolute: number; relative: number } + +export type StatsRow = AbsRelTuple & { + value: Record +} + +/** Search hits */ +export type ApiKwic = { + /** An object for each token in the context, with attribute values for that token */ + tokens: Token[] + /** Attribute values for the context (e.g. sentence) */ + structs: Record + /** Specifies the position of the match in the context. If `in_order` is false, `match` will consist of a list of match objects, one per highlighted word */ + match: KwicMatch | KwicMatch[] + /** Hits from aligned corpora if available, otherwise omitted */ + aligned: { + [linkedCorpusId: `${string}-${string}`]: Record[] + } +} + +/** Specifies the position of a match in a context */ +type KwicMatch = { + /** Start position of the match within the context */ + start: number + /** End position of the match within the context */ + end: number + /** Global corpus position of the match */ + position: number +} + +export type Token = { + word: string + structs?: { + open?: Record>[] + close?: string[] + } + [attr: string]: any +} diff --git a/app/scripts/controllers/example_controller.ts b/app/scripts/controllers/example_controller.ts index 27a49801..66327f8f 100644 --- a/app/scripts/controllers/example_controller.ts +++ b/app/scripts/controllers/example_controller.ts @@ -6,10 +6,10 @@ import { KwicCtrl, KwicCtrlScope } from "./kwic_controller" import { LocationService } from "@/urlparams" import { KwicTab, RootScope } from "@/root-scope.types" import { KorpResponse, ProgressReport } from "@/backend/types" -import { KorpQueryResponse } from "@/backend/kwic-proxy" import { UtilsService } from "@/services/utils" import "@/services/utils" import { TabHashScope } from "@/directives/tab-hash" +import { QueryResponse } from "@/backend/client" const korpApp = angular.module("korpApp") @@ -21,10 +21,10 @@ type ExampleCtrlScope = ScopeBase & { hitsPictureData?: any hitspictureClick?: (page: number) => void kwicTab: KwicTab - makeRequest: (isPaging?: boolean) => JQuery.jqXHR> + makeRequest: (isPaging?: boolean) => JQuery.jqXHR> onExampleProgress: (progressObj: ProgressReport, isPaging?: boolean) => void setupReadingWatch: () => void - superRenderResult: (data: KorpResponse) => void + superRenderResult: (data: KorpResponse) => void } class ExampleCtrl extends KwicCtrl { diff --git a/app/scripts/controllers/kwic_controller.ts b/app/scripts/controllers/kwic_controller.ts index 751cc6da..a5b8fcc2 100644 --- a/app/scripts/controllers/kwic_controller.ts +++ b/app/scripts/controllers/kwic_controller.ts @@ -2,20 +2,21 @@ import angular, { IController, ITimeoutService } from "angular" import _ from "lodash" import settings from "@/settings" -import kwicProxyFactory, { ApiKwic, KorpQueryParams, KorpQueryResponse, type KwicProxy } from "@/backend/kwic-proxy" +import kwicProxyFactory, { type KwicProxy } from "@/backend/kwic-proxy" import { RootScope } from "@/root-scope.types" import { LocationService } from "@/urlparams" -import { KorpResponse, ProgressReport } from "@/backend/types" +import { ApiKwic, KorpResponse, ProgressReport } from "@/backend/types" import { UtilsService } from "@/services/utils" import "@/services/utils" import { TabHashScope } from "@/directives/tab-hash" +import { QueryParams, QueryResponse } from "@/backend/client" angular.module("korpApp").directive("kwicCtrl", () => ({ controller: KwicCtrl })) export type KwicCtrlScope = TabHashScope & { active?: boolean aborted?: boolean - buildQueryOptions: (isPaging: boolean) => KorpQueryParams + buildQueryOptions: (isPaging: boolean) => QueryParams corpusHits?: Record countCorpora?: () => number | null corpusOrder?: string[] @@ -44,8 +45,8 @@ export type KwicCtrlScope = TabHashScope & { randomSeed?: number reading_mode?: boolean readingChange: () => void - renderCompleteResult: (data: KorpResponse, isPaging?: boolean) => void - renderResult: (data: KorpResponse) => void + renderCompleteResult: (data: KorpResponse, isPaging?: boolean) => void + renderResult: (data: KorpResponse) => void tabindex?: number toggleReading: () => void } @@ -181,7 +182,7 @@ export class KwicCtrl implements IController { const cqp = s.cqp || s.proxy.prevCQP if (!cqp) throw new Error("cqp missing") - const params: KorpQueryParams = { + const params: QueryParams = { corpus: settings.corpusListing.stringifySelected(), cqp, query_data: s.proxy.queryData, @@ -219,7 +220,7 @@ export class KwicCtrl implements IController { (progressObj) => $timeout(() => s.onProgress(progressObj, isPaging)), (data) => $timeout(() => s.renderResult(data)) ) - req.done((data: KorpResponse) => { + req.done((data: KorpResponse) => { $timeout(() => { s.loading = false s.renderCompleteResult(data, isPaging) diff --git a/app/scripts/controllers/text_reader_controller.ts b/app/scripts/controllers/text_reader_controller.ts index 09f1207d..1547da35 100644 --- a/app/scripts/controllers/text_reader_controller.ts +++ b/app/scripts/controllers/text_reader_controller.ts @@ -8,9 +8,9 @@ import "@/components/readingmode" import { RootScope, TextTab } from "@/root-scope.types" import { CorpusTransformed } from "@/settings/config-transformed.types" import { kebabize } from "@/util" -import { ApiKwic, Token } from "@/backend/kwic-proxy" import { TabHashScope } from "@/directives/tab-hash" import { getDataForReadingMode } from "@/backend/backend" +import { ApiKwic, Token } from "@/backend/types" type TextReaderControllerScope = TabHashScope & { loading: boolean diff --git a/app/scripts/kwic_download.ts b/app/scripts/kwic_download.ts index 3b78b92a..25e33799 100644 --- a/app/scripts/kwic_download.ts +++ b/app/scripts/kwic_download.ts @@ -3,8 +3,9 @@ import _ from "lodash" import moment from "moment" import CSV from "comma-separated-values/csv" import { locObj } from "@/i18n" -import { type ApiKwic, type KorpQueryParams } from "@/backend/kwic-proxy" import { LangString } from "./i18n/types" +import { ApiKwic } from "./backend/types" +import { QueryParams } from "./backend/client" // This is what is returned by massageData in kwic.js type Row = ApiKwic | LinkedKwic | CorpusHeading @@ -39,7 +40,7 @@ function createFile(dataType: string, fileType: string, content: string) { return [filename, blobURL] } -function createSearchInfo(requestInfo: KorpQueryParams, totalHits: number) { +function createSearchInfo(requestInfo: QueryParams, totalHits: number) { return [ `## CQP query: ${requestInfo.cqp}`, `## context: ${requestInfo.default_context}`, @@ -165,7 +166,7 @@ function transformDataToKWIC(data: Row[], searchInfo: string[]) { return res } -function transformData(dataType: "annotations" | "kwic", data: Row[], requestInfo: KorpQueryParams, totalHits: number) { +function transformData(dataType: "annotations" | "kwic", data: Row[], requestInfo: QueryParams, totalHits: number) { const searchInfo = createSearchInfo(requestInfo, totalHits) if (dataType === "annotations") { return transformDataToAnnotations(data as AnnotationsRow[], searchInfo) @@ -189,7 +190,7 @@ export function makeDownload( dataType: "annotations" | "kwic", fileType: "csv" | "tsv", data: Row[], - requestInfo: KorpQueryParams, + requestInfo: QueryParams, totalHits: number ) { const table = transformData(dataType, data, requestInfo, totalHits) diff --git a/app/scripts/statistics.types.ts b/app/scripts/statistics.types.ts index 8605a1bd..31919915 100644 --- a/app/scripts/statistics.types.ts +++ b/app/scripts/statistics.types.ts @@ -1,6 +1,7 @@ /** @format*/ // TODO: Merge with @/interfaces/stats.ts +import { StatsColumn } from "./backend/types" import { SlickgridColumn } from "./statistics" import { Dataset } from "./statistics_worker" @@ -13,7 +14,7 @@ export type StatisticsWorkerMessage = { export type StatisticsWorkerResult = [Dataset, SlickgridColumn[], SearchParams] -/** Like `KorpStatsResponse` but the stats are necessarily arrays. */ +/** Like `CountResponse` but the stats are necessarily arrays. */ export type StatsNormalized = { corpora: { [name: string]: StatsColumn[] @@ -23,18 +24,6 @@ export type StatsNormalized = { time: number } -export type StatsColumn = { - sums: AbsRelTuple - rows: StatsRow[] -} - -/** Frequency count as absolute and relative (to some total size). */ -export type AbsRelTuple = { absolute: number; relative: number } - -export type StatsRow = AbsRelTuple & { - value: Record -} - export type SearchParams = { reduceVals: string[] ignoreCase: boolean diff --git a/app/scripts/statistics_worker.ts b/app/scripts/statistics_worker.ts index fe45081d..9e1e9d6d 100644 --- a/app/scripts/statistics_worker.ts +++ b/app/scripts/statistics_worker.ts @@ -6,7 +6,8 @@ import isArray from "lodash/isArray" import keys from "lodash/keys" import { RowsEntity } from "./interfaces/stats" -import { StatisticsWorkerMessage, StatsNormalized, StatsRow } from "./statistics.types" +import { StatisticsWorkerMessage, StatsNormalized } from "./statistics.types" +import { StatsRow } from "./backend/types" /* This is optimized code for transforming the statistics data.