annosearch 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.loadIndex = loadIndex;
13
+ const maniiifest_1 = require("maniiifest");
14
+ const utils_1 = require("./utils");
15
+ const errors_1 = require("./errors");
16
+ const quickwit_1 = require("./quickwit");
17
+ const contentType = 'application/x-ndjson';
18
+ const quickwitClient = (0, quickwit_1.createClient)(contentType);
19
+ function processAnnotations(indexId, parser) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ let currentParser = parser;
22
+ while (currentParser) {
23
+ const annotations = Array.from(currentParser.iterateAnnotationPageAnnotation());
24
+ if (annotations.length > 0) {
25
+ const payload = (0, utils_1.createJsonl)(annotations);
26
+ const response = yield quickwitClient.post(`${indexId}/ingest`, payload);
27
+ if (!response.data) {
28
+ throw new errors_1.AnnoSearchValidationError('No response data received from Quickwit');
29
+ }
30
+ // Check if the response is successful and has data
31
+ if (response.status === 200 && response.data) {
32
+ // Print a line of '+' symbols based on the batch length
33
+ console.log('|' + '+'.repeat(annotations.length) + '|');
34
+ }
35
+ else {
36
+ throw new errors_1.AnnoSearchValidationError('Failed to ingest data: Invalid response from Quickwit');
37
+ }
38
+ }
39
+ // Move to the next annotation page if available
40
+ const nextPageUrl = currentParser.getAnnotationPage().next;
41
+ if (nextPageUrl) {
42
+ const jsonData = yield (0, utils_1.fetchJson)(nextPageUrl);
43
+ if (!jsonData) {
44
+ throw new errors_1.AnnoSearchValidationError('No JSON data returned from fetchJson');
45
+ }
46
+ currentParser = new maniiifest_1.Maniiifest(jsonData, "AnnotationPage");
47
+ }
48
+ else {
49
+ currentParser = null;
50
+ }
51
+ }
52
+ });
53
+ }
54
+ function processAnnotationPageRef(indexId, annotationPageUrl) {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ const jsonData = yield (0, utils_1.fetchJson)(annotationPageUrl);
57
+ const parser = new maniiifest_1.Maniiifest(jsonData, "AnnotationPage");
58
+ yield processAnnotations(indexId, parser);
59
+ });
60
+ }
61
+ function processAnnotationPage(indexId, page) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ const parser = new maniiifest_1.Maniiifest(page, "AnnotationPage");
64
+ yield processAnnotations(indexId, parser);
65
+ });
66
+ }
67
+ function processManifest(indexId, manifestUrl) {
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ const jsonData = yield (0, utils_1.fetchJson)(manifestUrl);
70
+ const parser = new maniiifest_1.Maniiifest(jsonData);
71
+ const type = parser.getSpecificationType();
72
+ if (type !== 'Manifest') {
73
+ throw new errors_1.AnnoSearchParseError('Specification should be a Manifest');
74
+ }
75
+ const annotationPages = parser.iterateManifestCanvasW3cAnnotationPage();
76
+ for (const page of annotationPages) {
77
+ if (page.items) {
78
+ yield processAnnotationPage(indexId, page);
79
+ }
80
+ else {
81
+ yield processAnnotationPageRef(indexId, page.id);
82
+ }
83
+ }
84
+ });
85
+ }
86
+ function processCollection(indexId, collectionUrl) {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ const jsonData = yield (0, utils_1.fetchJson)(collectionUrl);
89
+ const parser = new maniiifest_1.Maniiifest(jsonData);
90
+ const type = parser.getSpecificationType();
91
+ if (type !== 'Collection') {
92
+ throw new errors_1.AnnoSearchParseError('Specification should be a Collection');
93
+ }
94
+ const manifests = parser.iterateCollectionManifest();
95
+ // need to remove count later once tested
96
+ let count = 0;
97
+ for (const item of manifests) {
98
+ if (count >= 1)
99
+ break;
100
+ const manifestRef = new maniiifest_1.Maniiifest(item);
101
+ const manifestId = manifestRef.getManifestId();
102
+ if (manifestId) {
103
+ yield processManifest(indexId, manifestId);
104
+ }
105
+ else {
106
+ throw new errors_1.AnnoSearchValidationError('Manifest ID is null');
107
+ }
108
+ count++;
109
+ }
110
+ });
111
+ }
112
+ function processAnnotationCollection(indexId, annotationCollectionUrl) {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ const jsonData = yield (0, utils_1.fetchJson)(annotationCollectionUrl);
115
+ const parser = new maniiifest_1.Maniiifest(jsonData, "AnnotationCollection");
116
+ const type = parser.getAnnotationCollectionType();
117
+ if (type !== 'AnnotationCollection') {
118
+ throw new errors_1.AnnoSearchParseError('Should be a W3C annotation collection');
119
+ }
120
+ const firstPage = parser.getAnnotationCollectionFirst();
121
+ if (typeof firstPage === 'string') { // means it is a URI
122
+ yield processAnnotationPageRef(indexId, firstPage);
123
+ }
124
+ else {
125
+ yield processAnnotationPage(indexId, firstPage);
126
+ }
127
+ });
128
+ }
129
+ function loadIndex(indexId, uri, type) {
130
+ return __awaiter(this, void 0, void 0, function* () {
131
+ if (!indexId.trim() || !uri.trim()) {
132
+ throw new errors_1.AnnoSearchValidationError('Invalid index or uri parameter');
133
+ }
134
+ console.log(`Loading ${type} from ${uri} into index ${indexId}`);
135
+ switch (type) {
136
+ case 'Manifest':
137
+ yield processManifest(indexId, uri);
138
+ break;
139
+ case 'Collection':
140
+ yield processCollection(indexId, uri);
141
+ break;
142
+ case 'AnnotationCollection':
143
+ yield processAnnotationCollection(indexId, uri);
144
+ break;
145
+ default:
146
+ throw new errors_1.AnnoSearchValidationError('unsupported type');
147
+ }
148
+ });
149
+ }
150
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/load.ts"],"names":[],"mappings":";;;;;;;;;;;AA2GA,8BAkBC;AA7HD,2CAAwC;AACxC,mCAAiD;AACjD,qCAA2E;AAC3E,yCAA0C;AAE1C,MAAM,WAAW,GAAG,sBAAsB,CAAC;AAC3C,MAAM,cAAc,GAAG,IAAA,uBAAY,EAAC,WAAW,CAAC,CAAC;AAEjD,SAAe,kBAAkB,CAAC,OAAe,EAAE,MAAW;;QAC1D,IAAI,aAAa,GAAG,MAAM,CAAC;QAC3B,OAAO,aAAa,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,+BAA+B,EAAE,CAAC,CAAC;YAChF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAA,mBAAW,EAAC,WAAW,CAAC,CAAC;gBACzC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,OAAO,SAAS,EAAE,OAAO,CAAC,CAAC;gBACzE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;oBACjB,MAAM,IAAI,kCAAyB,CAAC,yCAAyC,CAAC,CAAC;gBACnF,CAAC;gBACD,mDAAmD;gBACnD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;oBAC3C,wDAAwD;oBACxD,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;gBAC5D,CAAC;qBAAM,CAAC;oBACJ,MAAM,IAAI,kCAAyB,CAAC,uDAAuD,CAAC,CAAC;gBACjG,CAAC;YACL,CAAC;YAED,gDAAgD;YAChD,MAAM,WAAW,GAAG,aAAa,CAAC,iBAAiB,EAAE,CAAC,IAAI,CAAC;YAC3D,IAAI,WAAW,EAAE,CAAC;gBACd,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAS,EAAC,WAAW,CAAC,CAAC;gBAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACZ,MAAM,IAAI,kCAAyB,CAAC,sCAAsC,CAAC,CAAC;gBAChF,CAAC;gBACD,aAAa,GAAG,IAAI,uBAAU,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACJ,aAAa,GAAG,IAAI,CAAC;YACzB,CAAC;QACL,CAAC;IACL,CAAC;CAAA;AAED,SAAe,wBAAwB,CAAC,OAAe,EAAE,iBAAyB;;QAC9E,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAS,EAAC,iBAAiB,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,uBAAU,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC1D,MAAM,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;CAAA;AAED,SAAe,qBAAqB,CAAC,OAAe,EAAE,IAAS;;QAC3D,MAAM,MAAM,GAAG,IAAI,uBAAU,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QACtD,MAAM,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;CAAA;AAED,SAAe,eAAe,CAAC,OAAe,EAAE,WAAmB;;QAC/D,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAS,EAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,uBAAU,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,oBAAoB,EAAE,CAAC;QAC3C,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACtB,MAAM,IAAI,6BAAoB,CAAC,oCAAoC,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,eAAe,GAAG,MAAM,CAAC,sCAAsC,EAAE,CAAC;QACxE,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;YACjC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,MAAM,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACJ,MAAM,wBAAwB,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YACrD,CAAC;QACL,CAAC;IACL,CAAC;CAAA;AAED,SAAe,iBAAiB,CAAC,OAAe,EAAE,aAAqB;;QACnE,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAS,EAAC,aAAa,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,uBAAU,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,oBAAoB,EAAE,CAAC;QAC3C,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YACxB,MAAM,IAAI,6BAAoB,CAAC,sCAAsC,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,yBAAyB,EAAE,CAAC;QACrD,yCAAyC;QACzC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC3B,IAAI,KAAK,IAAI,CAAC;gBAAE,MAAM;YACtB,MAAM,WAAW,GAAG,IAAI,uBAAU,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC;YAC/C,IAAI,UAAU,EAAE,CAAC;gBACb,MAAM,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACJ,MAAM,IAAI,kCAAyB,CAAC,qBAAqB,CAAC,CAAC;YAC/D,CAAC;YACD,KAAK,EAAE,CAAC;QACZ,CAAC;IACL,CAAC;CAAA;AAED,SAAe,2BAA2B,CAAC,OAAe,EAAE,uBAA+B;;QACvF,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAS,EAAC,uBAAuB,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,uBAAU,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,MAAM,CAAC,2BAA2B,EAAE,CAAC;QAClD,IAAI,IAAI,KAAK,sBAAsB,EAAE,CAAC;YAClC,MAAM,IAAI,6BAAoB,CAAC,uCAAuC,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,4BAA4B,EAAE,CAAC;QACxD,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC,CAAC,oBAAoB;YACrD,MAAM,wBAAwB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACJ,MAAM,qBAAqB,CAAC,OAAO,EAAE,SAAgB,CAAC,CAAC;QAC3D,CAAC;IACL,CAAC;CAAA;AAED,SAAsB,SAAS,CAAC,OAAe,EAAE,GAAW,EAAE,IAAY;;QACtE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,kCAAyB,CAAC,gCAAgC,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,SAAS,GAAG,eAAe,OAAO,EAAE,CAAC,CAAC;QACjE,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,UAAU;gBACX,MAAM,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACpC,MAAM;YACV,KAAK,YAAY;gBACb,MAAM,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACtC,MAAM;YACV,KAAK,sBAAsB;gBACvB,MAAM,2BAA2B,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAChD,MAAM;YACV;gBACI,MAAM,IAAI,kCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAChE,CAAC;IACL,CAAC;CAAA"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ // FILE: logger.ts
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.logErrorHandler = logErrorHandler;
8
+ const utils_1 = require("./utils");
9
+ const pino_1 = __importDefault(require("pino"));
10
+ // Define the logger configuration
11
+ const logger = (0, pino_1.default)({
12
+ level: 'info', // Default log level
13
+ timestamp: pino_1.default.stdTimeFunctions.isoTime, // ISO time format for easier readability and consistency
14
+ formatters: {
15
+ level: (label) => ({ level: label }), // Single-line style for log levels
16
+ },
17
+ messageKey: 'msg', // Key for the log message
18
+ transport: {
19
+ target: 'pino-pretty', // Use pino-pretty to format logs in a readable way
20
+ options: {
21
+ colorize: true, // Adds color to the console output
22
+ singleLine: true, // Ensures logs appear in a single line for easier parsing and reading
23
+ },
24
+ },
25
+ });
26
+ // Middleware to log other errors using handleWebError
27
+ function logErrorHandler(error, req, res, next) {
28
+ (0, utils_1.handleWebError)(error, res);
29
+ }
30
+ exports.default = logger;
31
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":";AAAA,kBAAkB;;;;;AAyBlB,0CAEC;AAxBD,mCAAyC;AACzC,gDAAwB;AAExB,kCAAkC;AAClC,MAAM,MAAM,GAAG,IAAA,cAAI,EAAC;IAChB,KAAK,EAAE,MAAM,EAAG,oBAAoB;IACpC,SAAS,EAAE,cAAI,CAAC,gBAAgB,CAAC,OAAO,EAAG,yDAAyD;IACpG,UAAU,EAAE;QACR,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAG,mCAAmC;KAC7E;IACD,UAAU,EAAE,KAAK,EAAG,0BAA0B;IAC9C,SAAS,EAAE;QACP,MAAM,EAAE,aAAa,EAAG,mDAAmD;QAC3E,OAAO,EAAE;YACL,QAAQ,EAAE,IAAI,EAAG,mCAAmC;YACpD,UAAU,EAAE,IAAI,EAAG,sEAAsE;SAC5F;KACJ;CACJ,CAAC,CAAC;AAGH,sDAAsD;AACtD,SAAgB,eAAe,CAAC,KAAU,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB;IACvF,IAAA,sBAAc,EAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED,kBAAe,MAAM,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createClient = createClient;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const baseURL = process.env.QUICKWIT_BASE_URL || 'http://localhost:7280/api/v1/';
9
+ const timeout = parseInt(process.env.QUICKWIT_TIMEOUT || '5000', 10);
10
+ function createClient(contentType) {
11
+ return axios_1.default.create({
12
+ baseURL: baseURL,
13
+ headers: {
14
+ 'Content-Type': contentType,
15
+ },
16
+ timeout: timeout, // 5 seconds timeout
17
+ });
18
+ }
19
+ //# sourceMappingURL=quickwit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quickwit.js","sourceRoot":"","sources":["../../src/quickwit.ts"],"names":[],"mappings":";;;;;AAKA,oCAQC;AAbD,kDAA0B;AAE1B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,+BAA+B,CAAC;AACjF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAErE,SAAgB,YAAY,CAAC,WAA6E;IACtG,OAAO,eAAK,CAAC,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE;YACL,cAAc,EAAE,WAAW;SAC9B;QACD,OAAO,EAAE,OAAO,EAAE,oBAAoB;KACzC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.searchIndex = searchIndex;
13
+ const quickwit_1 = require("./quickwit");
14
+ const errors_1 = require("./errors");
15
+ const iiif_1 = require("./iiif");
16
+ const contentType = 'application/json';
17
+ const quickwitClient = (0, quickwit_1.createClient)(contentType);
18
+ function searchIndex(indexId, query, maxHits, page, searchUrl) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const startOffset = page * maxHits;
21
+ if (startOffset < 0) {
22
+ throw new errors_1.AnnoSearchValidationError('Invalid paging');
23
+ }
24
+ if (!query.trim()) {
25
+ throw new errors_1.AnnoSearchValidationError('Missing query parameter');
26
+ }
27
+ const response = yield quickwitClient.post(`${indexId}/search`, {
28
+ query: query,
29
+ max_hits: maxHits,
30
+ start_offset: startOffset,
31
+ });
32
+ if (response.status === 200 && response.data) {
33
+ return (0, iiif_1.makeSearchResponse)(indexId, response.data, searchUrl, query, maxHits, page);
34
+ }
35
+ else {
36
+ throw new errors_1.AnnoSearchValidationError('Failed to delete index');
37
+ }
38
+ });
39
+ }
40
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/search.ts"],"names":[],"mappings":";;;;;;;;;;;AAQA,kCAmBC;AA3BD,yCAA0C;AAC1C,qCAAqD;AACrD,iCAA4C;AAE5C,MAAM,WAAW,GAAG,kBAAkB,CAAC;AACvC,MAAM,cAAc,GAAG,IAAA,uBAAY,EAAC,WAAW,CAAC,CAAC;AAGjD,SAAsB,WAAW,CAAC,OAAe,EAAE,KAAa,EAAE,OAAe,EAAE,IAAY,EAAE,SAAiB;;QAC9G,MAAM,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC;QACnC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,kCAAyB,CAAC,gBAAgB,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,kCAAyB,CAAC,yBAAyB,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,OAAO,SAAS,EAAE;YAC5D,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,OAAO;YACjB,YAAY,EAAE,WAAW;SAC5B,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC3C,OAAO,IAAA,yBAAkB,EAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACvF,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,kCAAyB,CAAC,wBAAwB,CAAC,CAAC;QAClE,CAAC;IACL,CAAC;CAAA"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ // FILE: server.ts
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
27
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
28
+ return new (P || (P = Promise))(function (resolve, reject) {
29
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
30
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
31
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
32
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
33
+ });
34
+ };
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.serve = serve;
40
+ const express_1 = __importDefault(require("express"));
41
+ const package_json_1 = require("../package.json"); // Import version from package.json
42
+ const utils_1 = require("./utils");
43
+ const logger_1 = __importStar(require("./logger")); // Import shared logger
44
+ const pino_http_1 = __importDefault(require("pino-http"));
45
+ const errors_1 = require("./errors");
46
+ function serve(client) {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ const app = (0, express_1.default)();
49
+ const port = client.getPort();
50
+ const host = client.getHost();
51
+ app.use((0, pino_http_1.default)({ logger: logger_1.default }));
52
+ app.get('/:index/search', (req, res) => __awaiter(this, void 0, void 0, function* () {
53
+ try {
54
+ const { index = '' } = req.params;
55
+ const { q = '', page = '0' } = req.query;
56
+ const pageNumber = parseInt(page);
57
+ const maxHits = client.getMaxHits();
58
+ // Validate the 'page' parameter
59
+ if (!Number.isInteger(pageNumber) || pageNumber < 0) {
60
+ throw new errors_1.AnnoSearchValidationError('Invalid "page" parameter: must be a non-negative integer');
61
+ }
62
+ // Validate the 'maxHits' parameter
63
+ if (!Number.isInteger(maxHits) || maxHits <= 0) {
64
+ throw new errors_1.AnnoSearchValidationError('Invalid "maxHits" configuration: must be a positive integer');
65
+ }
66
+ const results = yield client.searchIndex(index, q, pageNumber);
67
+ res.json(results);
68
+ }
69
+ catch (error) {
70
+ (0, utils_1.handleWebError)(error, res);
71
+ }
72
+ }));
73
+ app.get('/version', (req, res) => __awaiter(this, void 0, void 0, function* () {
74
+ try {
75
+ res.json({ version: package_json_1.version });
76
+ }
77
+ catch (error) {
78
+ (0, utils_1.handleWebError)(error, res);
79
+ }
80
+ }));
81
+ app.use((req, res, next) => {
82
+ const error = new errors_1.AnnoSearchNotFoundError(`404 Not Found: ${req.method} ${req.originalUrl}`);
83
+ next(error);
84
+ });
85
+ app.use(logger_1.logErrorHandler);
86
+ app.listen(port, host, () => {
87
+ console.log(`Server is running on http://${host}:${port}`);
88
+ });
89
+ });
90
+ }
91
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";AAAA,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUlB,sBA6CC;AArDD,sDAA8B;AAE9B,kDAA0C,CAAC,mCAAmC;AAC9E,mCAAyC;AACzC,mDAAmD,CAAC,uBAAuB;AAC3E,0DAAiC;AACjC,qCAA8E;AAE9E,SAAsB,KAAK,CAAC,MAAkB;;QAC1C,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;QACtB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;QAE7B,GAAG,CAAC,GAAG,CAAC,IAAA,mBAAQ,EAAC,EAAE,MAAM,EAAN,gBAAM,EAAE,CAAC,CAAC,CAAC;QAE9B,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAO,GAAG,EAAE,GAAG,EAAE,EAAE;YACzC,IAAI,CAAC;gBACD,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;gBAClC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,IAAI,GAAG,GAAG,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC;gBACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAc,CAAC,CAAC;gBAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;gBACpC,gCAAgC;gBAChC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;oBAClD,MAAM,IAAI,kCAAyB,CAAC,0DAA0D,CAAC,CAAC;gBACpG,CAAC;gBACD,mCAAmC;gBACnC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;oBAC7C,MAAM,IAAI,kCAAyB,CAAC,6DAA6D,CAAC,CAAC;gBACvG,CAAC;gBACD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,KAAe,EAAE,CAAW,EAAE,UAAU,CAAC,CAAC;gBACnF,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBAClB,IAAA,sBAAc,EAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/B,CAAC;QACL,CAAC,CAAA,CAAC,CAAC;QAEH,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAO,GAAG,EAAE,GAAG,EAAE,EAAE;YACnC,IAAI,CAAC;gBACD,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAP,sBAAO,EAAE,CAAC,CAAC;YAC1B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,IAAA,sBAAc,EAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/B,CAAC;QACL,CAAC,CAAA,CAAC,CAAC;QAEH,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,KAAK,GAAG,IAAI,gCAAuB,CAAC,kBAAkB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;YAC7F,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,CAAC,wBAAe,CAAC,CAAC;QAEzB,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YACxB,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACP,CAAC;CAAA"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.printJson = printJson;
16
+ exports.logError = logError;
17
+ exports.handleError = handleError;
18
+ exports.handleWebError = handleWebError;
19
+ exports.fetchJson = fetchJson;
20
+ exports.createJsonl = createJsonl;
21
+ const axios_1 = __importDefault(require("axios"));
22
+ const errors_1 = require("./errors");
23
+ const axios_2 = require("axios");
24
+ const logger_1 = __importDefault(require("./logger")); // Import Pino logger instance
25
+ // Function to print the results
26
+ function printJson(results) {
27
+ console.log(JSON.stringify(results, null, 2)); // Print the returned JSON
28
+ }
29
+ // Function to log errors in a single-line JSON format
30
+ function logError(error, context = 'General') {
31
+ const errorObject = { context, error: {} };
32
+ if (error instanceof errors_1.AnnoSearchNetworkError || error instanceof axios_2.AxiosError) {
33
+ errorObject.error = { type: 'Network Error', message: error.message };
34
+ }
35
+ else if (error instanceof errors_1.AnnoSearchNotFoundError) {
36
+ errorObject.error = { type: 'Not Found Error', message: error.message };
37
+ }
38
+ else if (error instanceof errors_1.AnnoSearchParseError) {
39
+ errorObject.error = { type: 'Parse Error', message: error.message };
40
+ }
41
+ else if (error instanceof errors_1.AnnoSearchValidationError) {
42
+ errorObject.error = { type: 'Validation Error', message: error.message };
43
+ }
44
+ else if (error instanceof errors_1.AnnoSearchError) {
45
+ errorObject.error = { type: 'General AnnoSearch Error', message: error.message };
46
+ }
47
+ else if (error instanceof Error) {
48
+ errorObject.error = { type: 'General Error', message: error.message };
49
+ }
50
+ else {
51
+ errorObject.error = { type: 'Unknown Error', details: JSON.stringify(error) };
52
+ }
53
+ logger_1.default.error(JSON.stringify(errorObject)); // Log as a single-line JSON object
54
+ }
55
+ // Function to handle errors
56
+ function handleError(error) {
57
+ logError(error);
58
+ throw error;
59
+ }
60
+ function handleWebError(error, res) {
61
+ var _a;
62
+ logError(error, 'Web Request');
63
+ let statusCode = 500;
64
+ let errorMessage = 'An error occurred during processing';
65
+ switch (true) {
66
+ case error instanceof errors_1.AnnoSearchValidationError:
67
+ statusCode = 400;
68
+ errorMessage = `Validation error: ${error.message}`;
69
+ break;
70
+ case error instanceof axios_2.AxiosError:
71
+ statusCode = ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) || 503;
72
+ errorMessage = `Network error: ${error.message}`;
73
+ break;
74
+ case error instanceof errors_1.AnnoSearchNetworkError:
75
+ statusCode = 503;
76
+ errorMessage = `Network error: ${error.message}`;
77
+ break;
78
+ case error instanceof errors_1.AnnoSearchNotFoundError:
79
+ statusCode = 404;
80
+ errorMessage = `Not found: ${error.message}`;
81
+ break;
82
+ case error instanceof errors_1.AnnoSearchParseError:
83
+ statusCode = 400;
84
+ errorMessage = `Parse error: ${error.message}`;
85
+ break;
86
+ case error instanceof errors_1.AnnoSearchError:
87
+ statusCode = 400;
88
+ errorMessage = `Application error: ${error.message}`;
89
+ break;
90
+ case error instanceof Error:
91
+ statusCode = 500;
92
+ errorMessage = `General error: ${error.message}`;
93
+ break;
94
+ default:
95
+ errorMessage = error.message || 'Internal Server Error';
96
+ break;
97
+ }
98
+ res.status(statusCode).json({ error: errorMessage });
99
+ }
100
+ // Function to fetch JSON data
101
+ function fetchJson(url) {
102
+ return __awaiter(this, void 0, void 0, function* () {
103
+ const response = yield axios_1.default.get(url);
104
+ if (!response.data) {
105
+ throw new errors_1.AnnoSearchValidationError('No JSON data returned');
106
+ }
107
+ return response.data;
108
+ });
109
+ }
110
+ function createJsonl(data) {
111
+ if (Array.isArray(data)) {
112
+ return data.map(item => JSON.stringify(item)).join('\n') + '\n';
113
+ }
114
+ else {
115
+ return JSON.stringify(data) + '\n';
116
+ }
117
+ }
118
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "annosearch",
3
+ "version": "0.0.1",
4
+ "main": "dist/index.js",
5
+ "scripts": {
6
+ "build": "tsc",
7
+ "start": "ts-node src/index.ts",
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "keywords": [],
11
+ "author": "John P. T. Moore",
12
+ "license": "MIT",
13
+ "description": "",
14
+ "devDependencies": {
15
+ "@types/express": "^5.0.0",
16
+ "@types/node": "^22.8.4",
17
+ "@types/pino": "^7.0.4",
18
+ "@types/yargs": "^17.0.33",
19
+ "maniiifest": "^1.2.9",
20
+ "typescript": "^5.6.3"
21
+ },
22
+ "dependencies": {
23
+ "axios": "^1.7.7",
24
+ "express": "^4.21.1",
25
+ "pino": "^9.5.0",
26
+ "pino-http": "^10.3.0",
27
+ "pino-pretty": "^12.1.0",
28
+ "yaml": "^2.6.0",
29
+ "yargs": "^17.7.2"
30
+ }
31
+ }
@@ -0,0 +1,68 @@
1
+ import { searchIndex as searchFunction } from './search';
2
+ import { initIndex as initFunction } from './init';
3
+ import { deleteIndex as deleteFunction } from './delete';
4
+ import { loadIndex as loadFunction } from './load';
5
+
6
+ interface Config {
7
+ maxHits: number;
8
+ port: number;
9
+ host: string;
10
+ searchUrl: string;
11
+ }
12
+
13
+ function loadConfig(): Config {
14
+ return {
15
+ maxHits: parseInt(process.env.ANNOSEARCH_MAX_HITS || '20'),
16
+ port: parseInt(process.env.ANNOSEARCH_PORT || '3000'),
17
+ host: process.env.ANNOSEARCH_HOST || 'localhost',
18
+ searchUrl: process.env.ANNOSEARCH_PUBLIC_URL || 'http://localhost:3000',
19
+ };
20
+ }
21
+
22
+ class AnnoSearch {
23
+ private maxHits: number;
24
+ private port: number;
25
+ private host: string;
26
+ private searchUrl: string;
27
+
28
+ constructor({ maxHits, port, host, searchUrl }: Config = loadConfig()) {
29
+ this.maxHits = maxHits;
30
+ this.port = port;
31
+ this.host = host;
32
+ this.searchUrl = searchUrl;
33
+ }
34
+
35
+ getHost(): string {
36
+ return this.host;
37
+ }
38
+
39
+ getPort(): number {
40
+ return this.port;
41
+ }
42
+
43
+ getMaxHits(): number {
44
+ return this.maxHits;
45
+ }
46
+
47
+ getSearchUrl(): string {
48
+ return this.searchUrl;
49
+ }
50
+
51
+ async loadIndex(indexId: string, uri: string, type: string) {
52
+ return await loadFunction(indexId, uri, type);
53
+ }
54
+
55
+ async searchIndex(indexId: string, query: string, page: number) {
56
+ return searchFunction(indexId, query, this.maxHits, page, this.searchUrl);
57
+ }
58
+
59
+ async initIndex(indexId: string) {
60
+ return await initFunction(indexId);
61
+ }
62
+
63
+ async deleteIndex(indexId: string) {
64
+ return await deleteFunction(indexId);
65
+ }
66
+ }
67
+
68
+ export default AnnoSearch;
package/src/delete.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { createClient } from './quickwit';
2
+ import { AnnoSearchValidationError } from './errors';
3
+
4
+ const contentType = 'application/json';
5
+ const quickwitClient = createClient(contentType);
6
+
7
+ export async function deleteIndex(indexId: string) {
8
+ if (!indexId.trim()) {
9
+ throw new AnnoSearchValidationError('Invalid index parameter');
10
+ }
11
+ const response = await quickwitClient.delete(`indexes/${indexId}`);
12
+ if (response.status === 200 && response.data) {
13
+ console.log('Index deleted successfully');
14
+ } else {
15
+ throw new AnnoSearchValidationError('Failed to delete index');
16
+ }
17
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,33 @@
1
+ // errors.ts
2
+
3
+ export class AnnoSearchError extends Error {
4
+ constructor(message: string) {
5
+ super(message);
6
+ this.name = this.constructor.name;
7
+ Error.captureStackTrace(this, this.constructor); // Captures the correct stack trace
8
+ }
9
+ }
10
+
11
+ export class AnnoSearchValidationError extends AnnoSearchError {
12
+ constructor(message = 'Invalid input data') {
13
+ super(message);
14
+ }
15
+ }
16
+
17
+ export class AnnoSearchNetworkError extends AnnoSearchError {
18
+ constructor(message = 'Network error occurred') {
19
+ super(message);
20
+ }
21
+ }
22
+
23
+ export class AnnoSearchNotFoundError extends AnnoSearchError {
24
+ constructor(message = 'Resource not found') {
25
+ super(message);
26
+ }
27
+ }
28
+
29
+ export class AnnoSearchParseError extends AnnoSearchError {
30
+ constructor(message = 'Error parsing data') {
31
+ super(message);
32
+ }
33
+ }