hal-search 0.1.0 → 0.3.0

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Jey Puget Gil
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jey Puget Gil
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,214 +1,241 @@
1
- # hal-search
2
-
3
- A zero-dependency TypeScript library for querying and displaying articles from the [HAL Open Archive](https://hal.science/) API.
4
-
5
- ---
6
-
7
- ## Goal
8
-
9
- **hal-search** lets you embed a live, paginated list of academic publications from the HAL API into any web page with a single class instantiation. It handles:
10
-
11
- - Building the correct HAL API query from a user ID or free-text query
12
- - Fetching results at a configurable level of detail (minimal → full)
13
- - Rendering styled article cards with pagination
14
- - Exposing callbacks for results and errors
15
-
16
- ---
17
-
18
- ## Installation
19
-
20
- ```bash
21
- # from npm (once published)
22
- npm install hal-search
23
-
24
- # or use the built files directly
25
- dist/hal-search.es.js # ES module
26
- dist/hal-search.umd.js # UMD (browser global: window.HalSearch)
27
- ```
28
-
29
- ---
30
-
31
- ## Usage
32
-
33
- ### Basic example
34
-
35
- ```html
36
- <div id="publications"></div>
37
-
38
- <script type="module">
39
- import { HalSearch } from './dist/hal-search.es.js';
40
-
41
- const hs = new HalSearch({
42
- container: '#publications',
43
- lvl: 1,
44
- rows: 10,
45
- onResults: (res) => console.log(`${res.response.numFound} results`),
46
- onError: (err) => console.error(err.message),
47
- });
48
-
49
- hs.search({ uid: 'authIdHal_s:jdupont' });
50
- </script>
51
- ```
52
-
53
- ### Constructor options
54
-
55
- | Option | Type | Default | Description |
56
- |----------------|-----------------------------------|---------|-------------|
57
- | `container` | `HTMLElement \| string` | — | Target DOM element or CSS selector (optional if output='svg') |
58
- | `lvl` | `0 \| 1 \| 2 \| 3` | `1` | Level of detail (see below) |
59
- | `rows` | `number` | `10` | Results per page |
60
- | `apiBase` | `string` | HAL URL | Override the API base URL |
61
- | `injectStyles` | `boolean` | `true` | Auto-inject the default stylesheet |
62
- | `onResults` | `(res: HalApiResponse) => void` | | Called on every successful fetch |
63
- | `onError` | `(err: Error) => void` | | Called when the fetch fails |
64
-
65
- ### Methods
66
-
67
- | Method | Description |
68
- |--------|-------------|
69
- | `search({ uid, rows?, start? })` | Start a new search. Returns `Promise<SVGSVGElement>` if headless SVG mode. |
70
- | `setLevel(lvl)` | Change detail level and re-fetch. Returns `Promise<SVGSVGElement>` if headless SVG mode. |
71
- | `goToPage(n)` | Jump to page `n` (1-based). Returns `Promise<SVGSVGElement>` if headless SVG mode. |
72
- | `nextPage()` | Go to the next page. Returns `Promise<SVGSVGElement>` if headless SVG mode. |
73
- | `prevPage()` | Go to the previous page. Returns `Promise<SVGSVGElement>` if headless SVG mode. |
74
- | `destroy()` | Clear the container (if one was provided) |
75
-
76
- ### Headless SVG generation
77
-
78
- You can generate a standalone SVG without attaching it to the DOM by omitting the `container` option and setting `output: 'svg'`. The `search()` method (and pagination methods) will resolve with the SVG element.
79
-
80
- ```js
81
- const hs = new HalSearch({
82
- output: 'svg',
83
- lvl: 2,
84
- rows: 5,
85
- });
86
-
87
- const svgElement = await hs.search({ uid: 'authIdHal_s:jdupont' });
88
- document.body.appendChild(svgElement);
89
- ```
90
-
91
- ### Detail levels
92
-
93
- The `lvl` parameter controls which HAL fields are requested and how much information is shown per article.
94
-
95
- | Level | Name | Fields fetched | What is displayed |
96
- |-------|------|---------------|-------------------|
97
- | `0` | Minimal | `docid`, `label_s`, `uri_s` | Citation label + link |
98
- | `1` | Basic *(default)* | + `title_s`, `authFullName_s`, `publicationDate_s`, `docType_s` | Title, authors, year, document type |
99
- | `2` | Detailed | + `keyword_s`, `domain_s`, `openAccess_bool`, `language_s`, `conferenceTitle_s` | All of the above + tags, OA badge, conference |
100
- | `3` | Full | `*` (all fields) | Adds the abstract of the paper |
101
-
102
- ### Theming
103
-
104
- Default styles use CSS custom properties. Override any of them on the container or globally:
105
-
106
- ```css
107
- #publications {
108
- --hal-accent: #e63946;
109
- --hal-bg-article: #fff8f0;
110
- --hal-radius: 4px;
111
- }
112
- ```
113
-
114
- | Variable | Default |
115
- |----------|---------|
116
- | `--hal-accent` | `#0052cc` |
117
- | `--hal-accent-hover` | `#003d99` |
118
- | `--hal-bg` | `#ffffff` |
119
- | `--hal-bg-article` | `#fafafa` |
120
- | `--hal-border` | `#e0e0e0` |
121
- | `--hal-text` | `#1a1a1a` |
122
- | `--hal-text-muted` | `#666666` |
123
- | `--hal-radius` | `6px` |
124
-
125
- Disable auto-injection with `injectStyles: false` and provide your own stylesheet.
126
-
127
- ### Building a query
128
-
129
- The `uid` field passed to `search()` maps directly to the `q` parameter of the HAL Solr API, so any valid Solr query works:
130
-
131
- ```js
132
- // Free-text
133
- hs.search({ uid: 'machine learning' });
134
-
135
- // Author by HAL identifier
136
- hs.search({ uid: 'authIdHal_s:jdupont' });
137
-
138
- // By lab structure
139
- hs.search({ uid: 'structId_i:123456' });
140
- ```
141
-
142
- See the [HAL API documentation](https://api.archives-ouvertes.fr/docs/search) for the full query syntax.
143
-
144
- ---
145
-
146
- ## Running the example
147
-
148
- ```bash
149
- npm run example
150
- ```
151
-
152
- This builds the library and serves the interactive demo at **http://localhost:8080/example/**. The demo lets you switch queries, levels, and page size in real time.
153
-
154
- To run the development sandbox (requires Vite):
155
-
156
- ```bash
157
- npm run dev
158
- # open http://localhost:5173
159
- ```
160
-
161
- ---
162
-
163
- ## Contributing
164
-
165
- ### Project structure
166
-
167
- ```
168
- src/
169
- index.ts # Public exports
170
- HalSearch.ts # Main class
171
- api.ts # URL builder + fetch logic
172
- levels.ts # Field lists per detail level
173
- renderer.ts # DOM rendering
174
- styles.ts # Default CSS
175
- types.ts # TypeScript interfaces
176
- example/
177
- index.html # Interactive demo
178
- dist/ # Built output (generated)
179
- ```
180
-
181
- ### Development setup
182
-
183
- ```bash
184
- git clone <repo>
185
- cd hal-search
186
- npm install
187
- npm run dev # live dev server at localhost:5173
188
- ```
189
-
190
- ### Building
191
-
192
- ```bash
193
- npm run build
194
- ```
195
-
196
- Produces:
197
-
198
- | File | Format | Use case |
199
- |------|--------|----------|
200
- | `dist/hal-search.es.js` | ES module | Bundlers, `<script type="module">` |
201
- | `dist/hal-search.umd.js` | UMD | `<script>` tag, CommonJS |
202
- | `dist/index.d.ts` | TypeScript types | TypeScript consumers |
203
-
204
- ### Guidelines
205
-
206
- - **TypeScript strict mode** is enabled — all code must type-check cleanly.
207
- - Keep the library **zero-dependency** at runtime; dev dependencies are fine.
208
- - Rendering lives in `renderer.ts`, API logic in `api.ts` — keep concerns separated.
209
- - Test new features against both the dev sandbox (`index.html`) and the example page (`example/index.html`).
210
- - Follow the existing naming conventions for CSS classes (`.hal-*`).
211
-
212
- ### Useful link
213
-
214
- - [HAL API documentation](https://api.archives-ouvertes.fr/docs/search)
1
+ # hal-search
2
+
3
+ A zero-dependency TypeScript library for querying and displaying articles from the [HAL Open Archive](https://hal.science/) API.
4
+
5
+ ---
6
+
7
+ ## Goal
8
+
9
+ **hal-search** lets you embed a live, paginated list of academic publications from the HAL API into any web page with a single class instantiation. It handles:
10
+
11
+ - Building the correct HAL API query from a user ID or free-text query
12
+ - Fetching results at a configurable level of detail (minimal → full)
13
+ - Rendering styled article cards with pagination
14
+ - Exposing callbacks for results and errors
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ # from npm (once published)
22
+ npm install hal-search
23
+
24
+ # or use the built files directly
25
+ dist/hal-search.es.js # ES module
26
+ dist/hal-search.umd.js # UMD (browser global: window.HalSearch)
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Usage
32
+
33
+ ### Basic example
34
+
35
+ ```html
36
+ <div id="publications"></div>
37
+
38
+ <script type="module">
39
+ import { HalSearch } from './dist/hal-search.es.js';
40
+
41
+ const hs = new HalSearch({
42
+ container: '#publications',
43
+ lvl: 1,
44
+ rows: 10,
45
+ onResults: (res) => console.log(`${res.response.numFound} results`),
46
+ onError: (err) => console.error(err.message),
47
+ });
48
+
49
+ hs.search({ uid: 'authIdHal_s:jdupont' });
50
+ </script>
51
+ ```
52
+
53
+ ### Constructor options
54
+
55
+ | Option | Type | Default | Description |
56
+ |----------------|-----------------------------------|---------|-------------|
57
+ | `container` | `HTMLElement \| string` | — | Target DOM element or CSS selector (optional if output='svg') |
58
+ | `lvl` | `0 \| 1 \| 2 \| 3` | `1` | Level of detail (see below) |
59
+ | `rows` | `number` | `10` | Results per page |
60
+ | `apiBase` | `string` | HAL URL | Override the API base URL |
61
+ | `injectStyles` | `boolean` | `true` | Auto-inject the default stylesheet |
62
+ | `backgroundColor` | `string` | `#ffffff` | Background color for article cards (sets `--hal-bg`) |
63
+ | `textColor` | `string` | `#1a1a1a` | Text color for article content (sets `--hal-text`) |
64
+ | `mainColor` | `string` | `#0052cc` | Accent color for links, buttons, and highlights (sets `--hal-accent`) |
65
+ | `onResults` | `(res: HalApiResponse) => void` | — | Called on every successful fetch |
66
+ | `onError` | `(err: Error) => void` | — | Called when the fetch fails |
67
+
68
+ ### Methods
69
+
70
+ | Method | Description |
71
+ |--------|-------------|
72
+ | `search({ uid, rows?, start? })` | Start a new search. Returns `Promise<SVGSVGElement>` if headless SVG mode. |
73
+ | `setLevel(lvl)` | Change detail level and re-fetch. Returns `Promise<SVGSVGElement>` if headless SVG mode. |
74
+ | `goToPage(n)` | Jump to page `n` (1-based). Returns `Promise<SVGSVGElement>` if headless SVG mode. |
75
+ | `nextPage()` | Go to the next page. Returns `Promise<SVGSVGElement>` if headless SVG mode. |
76
+ | `prevPage()` | Go to the previous page. Returns `Promise<SVGSVGElement>` if headless SVG mode. |
77
+ | `setColors({ backgroundColor?, textColor?, mainColor? })` | Update colors at runtime. Only provided colors are changed. |
78
+ | `destroy()` | Clear the container (if one was provided) |
79
+
80
+ ### Headless SVG generation
81
+
82
+ You can generate a standalone SVG without attaching it to the DOM by omitting the `container` option and setting `output: 'svg'`. The `search()` method (and pagination methods) will resolve with the SVG element.
83
+
84
+ ```js
85
+ const hs = new HalSearch({
86
+ output: 'svg',
87
+ lvl: 2,
88
+ rows: 5,
89
+ });
90
+
91
+ const svgElement = await hs.search({ uid: 'authIdHal_s:jdupont' });
92
+ document.body.appendChild(svgElement);
93
+ ```
94
+
95
+ ### Detail levels
96
+
97
+ The `lvl` parameter controls which HAL fields are requested and how much information is shown per article.
98
+
99
+ | Level | Name | Fields fetched | What is displayed |
100
+ |-------|------|---------------|-------------------|
101
+ | `0` | Minimal | `docid`, `label_s`, `uri_s` | Citation label + link |
102
+ | `1` | Basic *(default)* | + `title_s`, `authFullName_s`, `publicationDate_s`, `docType_s` | Title, authors, year, document type |
103
+ | `2` | Detailed | + `keyword_s`, `domain_s`, `openAccess_bool`, `language_s`, `conferenceTitle_s` | All of the above + tags, OA badge, conference |
104
+ | `3` | Full | `*` (all fields) | Adds the abstract of the paper |
105
+
106
+ ### Color customization
107
+
108
+ You can set the three main colors directly via constructor options:
109
+
110
+ ```js
111
+ const hs = new HalSearch({
112
+ container: '#publications',
113
+ backgroundColor: '#1a1a2e', // dark background
114
+ textColor: '#e0e0e0', // light text
115
+ mainColor: '#e63946', // red accent
116
+ });
117
+ ```
118
+
119
+ Colors can also be changed at runtime without re-fetching:
120
+
121
+ ```js
122
+ hs.setColors({
123
+ backgroundColor: '#ffffff',
124
+ textColor: '#1a1a1a',
125
+ mainColor: '#0052cc',
126
+ });
127
+ ```
128
+
129
+ ### Theming
130
+
131
+ For finer control, default styles use CSS custom properties. Override any of them on the container or globally:
132
+
133
+ ```css
134
+ #publications {
135
+ --hal-accent: #e63946;
136
+ --hal-bg-article: #fff8f0;
137
+ --hal-radius: 4px;
138
+ }
139
+ ```
140
+
141
+ | Variable | Default |
142
+ |----------|---------|
143
+ | `--hal-accent` | `#0052cc` |
144
+ | `--hal-accent-hover` | `#003d99` |
145
+ | `--hal-bg` | `#ffffff` |
146
+ | `--hal-bg-article` | `#fafafa` |
147
+ | `--hal-border` | `#e0e0e0` |
148
+ | `--hal-text` | `#1a1a1a` |
149
+ | `--hal-text-muted` | `#666666` |
150
+ | `--hal-radius` | `6px` |
151
+
152
+ Disable auto-injection with `injectStyles: false` and provide your own stylesheet.
153
+
154
+ ### Building a query
155
+
156
+ The `uid` field passed to `search()` maps directly to the `q` parameter of the HAL Solr API, so any valid Solr query works:
157
+
158
+ ```js
159
+ // Free-text
160
+ hs.search({ uid: 'machine learning' });
161
+
162
+ // Author by HAL identifier
163
+ hs.search({ uid: 'authIdHal_s:jdupont' });
164
+
165
+ // By lab structure
166
+ hs.search({ uid: 'structId_i:123456' });
167
+ ```
168
+
169
+ See the [HAL API documentation](https://api.archives-ouvertes.fr/docs/search) for the full query syntax.
170
+
171
+ ---
172
+
173
+ ## Running the example
174
+
175
+ ```bash
176
+ npm run example
177
+ ```
178
+
179
+ This builds the library and serves the interactive demo at **http://localhost:8080/example/**. The demo lets you switch queries, levels, and page size in real time.
180
+
181
+ To run the development sandbox (requires Vite):
182
+
183
+ ```bash
184
+ npm run dev
185
+ # open http://localhost:5173
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Contributing
191
+
192
+ ### Project structure
193
+
194
+ ```
195
+ src/
196
+ index.ts # Public exports
197
+ HalSearch.ts # Main class
198
+ api.ts # URL builder + fetch logic
199
+ levels.ts # Field lists per detail level
200
+ renderer.ts # DOM rendering
201
+ styles.ts # Default CSS
202
+ types.ts # TypeScript interfaces
203
+ example/
204
+ index.html # Interactive demo
205
+ dist/ # Built output (generated)
206
+ ```
207
+
208
+ ### Development setup
209
+
210
+ ```bash
211
+ git clone <repo>
212
+ cd hal-search
213
+ npm install
214
+ npm run dev # live dev server at localhost:5173
215
+ ```
216
+
217
+ ### Building
218
+
219
+ ```bash
220
+ npm run build
221
+ ```
222
+
223
+ Produces:
224
+
225
+ | File | Format | Use case |
226
+ |------|--------|----------|
227
+ | `dist/hal-search.es.js` | ES module | Bundlers, `<script type="module">` |
228
+ | `dist/hal-search.umd.js` | UMD | `<script>` tag, CommonJS |
229
+ | `dist/index.d.ts` | TypeScript types | TypeScript consumers |
230
+
231
+ ### Guidelines
232
+
233
+ - **TypeScript strict mode** is enabled — all code must type-check cleanly.
234
+ - Keep the library **zero-dependency** at runtime; dev dependencies are fine.
235
+ - Rendering lives in `renderer.ts`, API logic in `api.ts` — keep concerns separated.
236
+ - Test new features against both the dev sandbox (`index.html`) and the example page (`example/index.html`).
237
+ - Follow the existing naming conventions for CSS classes (`.hal-*`).
238
+
239
+ ### Useful link
240
+
241
+ - [HAL API documentation](https://api.archives-ouvertes.fr/docs/search)
@@ -4,6 +4,7 @@ export declare class HalSearch {
4
4
  private options;
5
5
  private pagination;
6
6
  private currentUid;
7
+ private colorOverrides;
7
8
  constructor(options: HalSearchOptions);
8
9
  /** Start a new search, resetting to page 1. */
9
10
  search(params: SearchParams): Promise<SVGSVGElement | void>;
@@ -15,8 +16,15 @@ export declare class HalSearch {
15
16
  prevPage(): Promise<SVGSVGElement | void>;
16
17
  /** Change the detail level and re-fetch the current results. */
17
18
  setLevel(lvl: DetailLevel): Promise<SVGSVGElement | void>;
19
+ /** Update the color theme at runtime. Only provided colors are changed. */
20
+ setColors(colors: {
21
+ backgroundColor?: string;
22
+ textColor?: string;
23
+ mainColor?: string;
24
+ }): void;
18
25
  /** Clear the container and remove rendered content. */
19
26
  destroy(): void;
27
+ private _applyColors;
20
28
  private _fetch;
21
29
  private _resolveContainer;
22
30
  private _updatePagination;
package/dist/embed.d.ts CHANGED
@@ -14,6 +14,12 @@ export interface EmbedOptions {
14
14
  width?: string;
15
15
  /** iframe height (CSS value) */
16
16
  height?: string;
17
+ /** Background color for article cards */
18
+ backgroundColor?: string;
19
+ /** Text color for article content */
20
+ textColor?: string;
21
+ /** Main accent color for links and buttons */
22
+ mainColor?: string;
17
23
  }
18
24
  /** Builds the URL for the embeddable page with query parameters. */
19
25
  export declare function buildEmbedUrl(options: EmbedOptions): string;