@iebh/reflib 2.3.1 → 2.3.3

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,37 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "type": "node",
9
+ "request": "launch",
10
+ "name": "Run npm test:browser",
11
+ "runtimeExecutable": "/home/connor/.nvm/versions/node/v20.12.2/bin/npm",
12
+ "runtimeArgs": [
13
+ "run",
14
+ "test:browser"
15
+ ],
16
+ "console": "integratedTerminal"
17
+ },
18
+ {
19
+ "name": "Launch Chrome against localhost",
20
+ "type": "chrome",
21
+ "request": "launch",
22
+ "url": "http://localhost:3000",
23
+ "webRoot": "${workspaceFolder}/test/browser"
24
+ },
25
+ {
26
+ "name": "Attach to Vite Server",
27
+ "type": "node",
28
+ "request": "attach",
29
+ "port": 9229,
30
+ "address": "localhost",
31
+ "restart": true,
32
+ "skipFiles": [
33
+ "<node_internals>/**"
34
+ ]
35
+ }
36
+ ]
37
+ }
@@ -1,19 +1,8 @@
1
1
  import camelCase from '../shared/camelCase.js';
2
2
  import Emitter from '../shared/emitter.js';
3
3
 
4
- // Only import WritableStream on node
5
- // This is needed even with the "browser" field of package.json
6
- let XMLParser;
7
- if (typeof window === 'undefined') {
8
- // We are in node env
9
- import('htmlparser2/lib/WritableStream').then(module => {
10
- XMLParser = module.WritableStream;
11
- });
12
- } else {
13
- // Handle or ignore in browser environment
14
- console.log("WritableStream not loaded in browser.");
15
- }
16
-
4
+ // This import is overwritten by the 'browser' field in package.json with the shimmed version
5
+ import { WritableStream as XMLParser } from 'htmlparser2/lib/WritableStream';
17
6
 
18
7
  /**
19
8
  * @see modules/inhterface.js
@@ -42,59 +31,6 @@ export function readStream(stream) {
42
31
  */
43
32
  let textAppend = false;
44
33
 
45
- class XMLParserBrowser {
46
- constructor(passedParserOptions) {
47
- // Stores XML in text form once read
48
- this.text = "";
49
- this.emitter = emitter;
50
- // Add event listeners to mimic htmlparser2 behavior in the browser
51
- this.emitter.on('opentag', passedParserOptions.onopentag);
52
- this.emitter.on('closetag', passedParserOptions.onclosetag);
53
- this.emitter.on('text', passedParserOptions.ontext);
54
- }
55
-
56
- write(data) {
57
- // CF: TODO: Parse data as it comes in chunks for better memory efficiency
58
- this.text += data;
59
- }
60
-
61
- end() {
62
- this.parseXML(this.text);
63
- // Free memory
64
- this.text = ''
65
- this.emitter.emit('end');
66
- }
67
-
68
- parseXML(xmlString) {
69
- let parser = new DOMParser();
70
- let doc = parser.parseFromString(xmlString, 'application/xml');
71
- this.traverseNode(doc.documentElement);
72
- }
73
-
74
- traverseNode(node) {
75
- if (node.nodeType === Node.ELEMENT_NODE) {
76
- let name = camelCase(node.nodeName);
77
- let attrs = Array.from(node.attributes).reduce((acc, attr) => {
78
- acc[attr.name] = attr.value;
79
- return acc;
80
- }, {});
81
-
82
- this.emitter.emit('opentag', name, attrs);
83
-
84
- for (let child of node.childNodes) {
85
- this.traverseNode(child);
86
- }
87
-
88
- this.emitter.emit('closetag', name);
89
- } else if (node.nodeType === Node.TEXT_NODE) {
90
- let text = node.nodeValue.trim();
91
- if (text) {
92
- this.emitter.emit('text', text);
93
- }
94
- }
95
- }
96
- }
97
-
98
34
  /**
99
35
  * The options/callbacks for the parser
100
36
  * @type {Object}
@@ -168,18 +104,7 @@ export function readStream(stream) {
168
104
  // Queue up the parser in the next tick (so we can return the emitter first)
169
105
  setTimeout(() => {
170
106
 
171
- if (stream.isBrowser === true) {
172
- // We are on the node.js client
173
- console.log('Loading EndNote library as node.js')
174
- let parser = new XMLParserBrowser(parserOptions);
175
- stream.on('data', ()=> emitter.emit('progress', stream.bytesRead))
176
- stream.pipe(parser)
177
- return;
178
- }
179
-
180
- else if (typeof stream.pipe === 'function') {
181
- // We are on the node.js client
182
- console.log('Loading EndNote library as node.js')
107
+ if (typeof stream.pipe === 'function') {
183
108
  let parser = new XMLParser(parserOptions);
184
109
  stream.on('data', ()=> emitter.emit('progress', stream.bytesRead))
185
110
  stream.pipe(parser)
@@ -187,7 +112,7 @@ export function readStream(stream) {
187
112
  }
188
113
 
189
114
  else {
190
- console.error('Error determining if on browser or node')
115
+ console.error('Error with stream, check "streamEmitter.js" if on browser')
191
116
  }
192
117
 
193
118
  })
package/modules/json.js CHANGED
@@ -1,45 +1,7 @@
1
1
  import Emitter from '../shared/emitter.js';
2
+ // This import is overwritten by the 'browser' field in package.json with the shimmed version
2
3
  import JSONStream from 'JSONStream';
3
4
 
4
- class BrowserJSONStream {
5
- constructor() {
6
- this.text = '';
7
- this.emitter = Emitter();
8
- }
9
-
10
- write(data) {
11
- // CF: TODO: Parse data as it comes in chunks for better memory efficiency
12
- this.text += data
13
- }
14
-
15
- end() {
16
- try {
17
- // Parse this.text as JSON
18
- const jsonArray = JSON.parse(this.text);
19
- // Free memory
20
- this.text = ''
21
-
22
- // For each entry in the json array (as ref):
23
- jsonArray.forEach(ref => {
24
- this.emitter.emit('ref', {
25
- recNumber: this.recNumber++,
26
- ...ref,
27
- });
28
- });
29
-
30
- // Finished
31
- this.emitter.emit('end');
32
- } catch (e) {
33
- console.error('Error parsing final JSON:', e);
34
- this.emitter.emit('error', e);
35
- }
36
- }
37
-
38
- on(event, listener) {
39
- this.emitter.on(event, listener);
40
- }
41
- }
42
-
43
5
  /**
44
6
  * @see modules/interface.js
45
7
  */
@@ -51,34 +13,21 @@ export function readStream(stream) {
51
13
  setTimeout(()=> {
52
14
  stream.on('data', ()=> emitter.emit('progress', stream.bytesRead));
53
15
 
54
- if (stream.isBrowser === true) {
55
- // On browser
56
- console.log('Parsing JSON natively in browser');
57
- const browserJSONStream = new BrowserJSONStream();
58
- browserJSONStream.on('ref', (data) => {
59
- emitter.emit('ref', data);
60
- });
61
- browserJSONStream.on('end', () => emitter.emit('end'));
62
- browserJSONStream.on('error', (error) => emitter.emit('error', error));
63
- stream.pipe(browserJSONStream);
64
- }
65
-
66
- else if (typeof stream.pipe === 'function') {
16
+ if (typeof stream.pipe === 'function') {
67
17
  // On node.js
68
18
  console.log('Parsing JSON with node.js library')
69
19
  const nodeJSONStream = JSONStream.parse('*')
70
- nodeJSONStream
71
- .on('data', ref => emitter.emit('ref', {
72
- recNumber: recNumber++,
73
- ...ref,
74
- }))
75
- .on('end', ()=> emitter.emit('end'))
76
- .on('error', emitter.emit.bind('error'));
20
+ nodeJSONStream.on('data', ref => emitter.emit('ref', {
21
+ recNumber: recNumber++,
22
+ ...ref,
23
+ }))
24
+ nodeJSONStream.on('end', ()=> emitter.emit('end'))
25
+ nodeJSONStream.on('error', emitter.emit.bind('error'));
77
26
  stream.pipe(nodeJSONStream)
78
27
  }
79
28
 
80
29
  else {
81
- console.error('Error determining if on browser or node')
30
+ console.error('Error with stream, check "streamEmitter.js" if on browser')
82
31
  }
83
32
  });
84
33
 
@@ -0,0 +1,42 @@
1
+ import Emitter from '../../shared/emitter.js';
2
+
3
+ export default class BrowserJSONStream {
4
+ constructor() {
5
+ this.text = '';
6
+ this.emitter = Emitter();
7
+ this.recNumber = 1;
8
+ }
9
+
10
+ write(data) {
11
+ // CF: TODO: Parse data as it comes in chunks for better memory efficiency
12
+ this.text += data;
13
+ }
14
+
15
+ end() {
16
+ try {
17
+ // Parse this.text as JSON
18
+ const jsonArray = JSON.parse(this.text);
19
+ // Free memory
20
+ this.text = '';
21
+
22
+ // For each entry in the json array (as ref):
23
+ jsonArray.forEach(ref => {
24
+ this.emitter.emit('data', ref);
25
+ });
26
+
27
+ // Finished
28
+ this.emitter.emit('end');
29
+ } catch (e) {
30
+ console.error('Error parsing final JSON:', e);
31
+ this.emitter.emit('error', e);
32
+ }
33
+ }
34
+
35
+ on(event, listener) {
36
+ this.emitter.on(event, listener);
37
+ }
38
+
39
+ static parse() {
40
+ return new BrowserJSONStream();
41
+ }
42
+ }
@@ -0,0 +1,57 @@
1
+ import camelCase from '../../shared/camelCase.js';
2
+ import Emitter from '../../shared/emitter.js';
3
+ import CacxParser from '@iebh/cacx';
4
+
5
+ export class WritableStream {
6
+ constructor(passedParserOptions) {
7
+ this.emitter = Emitter();
8
+ this.parser = new CacxParser({
9
+ collect: false,
10
+ onTagOpen: (node) => {
11
+ const name = camelCase(node.tag);
12
+ const attrs = node.attrs || {};
13
+ this.emitter.emit('opentag', name, attrs);
14
+ },
15
+ onTagClose: (node) => {
16
+ const name = camelCase(node.tag);
17
+ this.emitter.emit('closetag', name);
18
+ },
19
+ onAttr: (key, val/*, options*/) => {
20
+ // This method is called for each attribute, so we don't need to do anything here
21
+ return { [key]: val };
22
+ },
23
+ flattenText: true,
24
+ keyText: 'text',
25
+ keyAttrs: 'attrs',
26
+ });
27
+
28
+ // Add event listeners to mimic htmlparser2 behavior
29
+ this.emitter.on('opentag', passedParserOptions.onopentag);
30
+ this.emitter.on('closetag', passedParserOptions.onclosetag);
31
+ this.emitter.on('text', passedParserOptions.ontext);
32
+ this.emitter.on('end', passedParserOptions.onend);
33
+ }
34
+
35
+ write(data) {
36
+ this.parser.append(data).exec();
37
+
38
+ // Emit text events for any text nodes
39
+ const currentNode = this.parser.stack.at(-1);
40
+ if (currentNode && currentNode.text) {
41
+ const text = currentNode.text.trim();
42
+ if (text) {
43
+ this.emitter.emit('text', text);
44
+ }
45
+ // Clear the text to avoid emitting it multiple times
46
+ currentNode.text = '';
47
+ }
48
+ }
49
+
50
+ end() {
51
+ // Process any remaining data
52
+ this.parser.exec();
53
+
54
+ // Emit end event
55
+ this.emitter.emit('end');
56
+ }
57
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iebh/reflib",
3
- "version": "2.3.1",
3
+ "version": "2.3.3",
4
4
  "description": "Reference / Citation reference library utilities",
5
5
  "scripts": {
6
6
  "lint": "eslint lib modules shared test",
@@ -39,9 +39,9 @@
39
39
  "./*": "./lib/*.js"
40
40
  },
41
41
  "browser": {
42
- "htmlparser2/lib/WritableStream": false,
43
- "htmlparser2/lib/esm/WritableStream": false,
44
- "JSONStream": false
42
+ "htmlparser2/lib/WritableStream": "./modules/shims/WritableStream-browser.js",
43
+ "htmlparser2/lib/esm/WritableStream": "./modules/shims/WritableStream-browser.js",
44
+ "JSONStream": "./modules/shims/JSONStream-browser.js"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@momsfriendlydevco/eslint-config": "^1.0.9",
@@ -53,6 +53,7 @@
53
53
  "vite-plugin-replace": "^0.1.1"
54
54
  },
55
55
  "dependencies": {
56
+ "@iebh/cacx": "^1.0.0",
56
57
  "htmlparser2": "^9.0.0",
57
58
  "JSONStream": "^1.3.5",
58
59
  "mitt": "^3.0.1"