rdflib 2.2.21 → 2.2.22-b51259b5

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.
Files changed (106) hide show
  1. package/dist/rdflib.min.js +1 -1
  2. package/dist/rdflib.min.js.LICENSE.txt +9 -1
  3. package/dist/rdflib.min.js.map +1 -1
  4. package/esm/blank-node.js +61 -114
  5. package/esm/class-order.js +1 -1
  6. package/esm/collection.js +70 -128
  7. package/esm/convert.js +1 -2
  8. package/esm/default-graph.js +14 -48
  9. package/esm/empty.js +8 -39
  10. package/esm/factories/canonical-data-factory.js +33 -65
  11. package/esm/factories/extended-term-factory.js +18 -25
  12. package/esm/factories/factory-types.js +3 -2
  13. package/esm/factories/rdflib-data-factory.js +9 -19
  14. package/esm/fetcher.js +1341 -1854
  15. package/esm/formula.js +639 -846
  16. package/esm/index.js +40 -76
  17. package/esm/jsonldparser.js +24 -49
  18. package/esm/jsonparser.js +1 -8
  19. package/esm/lists.js +47 -110
  20. package/esm/literal.js +120 -189
  21. package/esm/log.js +7 -7
  22. package/esm/n3parser.js +1015 -1412
  23. package/esm/named-node.js +70 -119
  24. package/esm/namespace.js +2 -5
  25. package/esm/node-internal.js +73 -110
  26. package/esm/node.js +2 -7
  27. package/esm/parse.js +12 -19
  28. package/esm/patch-parser.js +10 -30
  29. package/esm/query-to-sparql.js +0 -18
  30. package/esm/query.js +63 -147
  31. package/esm/rdfaparser.js +794 -997
  32. package/esm/rdfxmlparser.js +347 -461
  33. package/esm/serialize.js +9 -27
  34. package/esm/serializer.js +820 -1049
  35. package/esm/sparql-to-query.js +44 -134
  36. package/esm/statement.js +54 -85
  37. package/esm/store.js +830 -1103
  38. package/esm/types.js +22 -21
  39. package/esm/update-manager.js +869 -1106
  40. package/esm/updates-via.js +104 -161
  41. package/esm/uri.js +9 -53
  42. package/esm/utils/default-graph-uri.js +3 -2
  43. package/esm/utils/termValue.js +0 -1
  44. package/esm/utils/terms.js +19 -21
  45. package/esm/utils-js.js +20 -61
  46. package/esm/utils.js +10 -21
  47. package/esm/variable.js +32 -78
  48. package/esm/xsd.js +2 -2
  49. package/lib/blank-node.js +60 -113
  50. package/lib/class-order.js +1 -2
  51. package/lib/collection.js +69 -131
  52. package/lib/convert.js +3 -9
  53. package/lib/default-graph.js +13 -52
  54. package/lib/empty.js +8 -43
  55. package/lib/factories/canonical-data-factory.js +35 -79
  56. package/lib/factories/extended-term-factory.js +18 -32
  57. package/lib/factories/factory-types.d.ts +6 -6
  58. package/lib/factories/factory-types.js +1 -4
  59. package/lib/factories/rdflib-data-factory.js +9 -23
  60. package/lib/fetcher.d.ts +6 -6
  61. package/lib/fetcher.js +1370 -1843
  62. package/lib/formula.js +640 -855
  63. package/lib/index.js +66 -152
  64. package/lib/jsonldparser.js +23 -53
  65. package/lib/jsonparser.js +1 -10
  66. package/lib/lists.js +55 -112
  67. package/lib/literal.js +120 -195
  68. package/lib/log.d.ts +0 -6
  69. package/lib/log.js +7 -8
  70. package/lib/n3parser.js +1030 -1436
  71. package/lib/named-node.js +69 -126
  72. package/lib/namespace.js +2 -7
  73. package/lib/node-internal.js +74 -107
  74. package/lib/node.js +2 -12
  75. package/lib/parse.d.ts +1 -1
  76. package/lib/parse.js +12 -32
  77. package/lib/patch-parser.js +11 -34
  78. package/lib/query-to-sparql.js +0 -23
  79. package/lib/query.js +62 -167
  80. package/lib/rdfaparser.js +796 -1009
  81. package/lib/rdfxmlparser.js +349 -466
  82. package/lib/serialize.js +11 -37
  83. package/lib/serializer.js +823 -1064
  84. package/lib/sparql-to-query.js +42 -167
  85. package/lib/statement.js +55 -91
  86. package/lib/store.d.ts +1 -1
  87. package/lib/store.js +850 -1112
  88. package/lib/tf-types.d.ts +4 -4
  89. package/lib/types.d.ts +8 -8
  90. package/lib/types.js +23 -23
  91. package/lib/update-manager.d.ts +1 -1
  92. package/lib/update-manager.js +865 -1103
  93. package/lib/updates-via.js +105 -164
  94. package/lib/uri.js +8 -61
  95. package/lib/utils/default-graph-uri.js +3 -5
  96. package/lib/utils/termValue.js +0 -2
  97. package/lib/utils/terms.js +19 -40
  98. package/lib/utils-js.js +23 -88
  99. package/lib/utils.js +10 -27
  100. package/lib/variable.js +34 -85
  101. package/lib/xsd-internal.js +0 -3
  102. package/lib/xsd.js +2 -6
  103. package/package.json +35 -35
  104. package/src/fetcher.ts +2 -2
  105. package/src/update-manager.ts +12 -7
  106. package/changes.txt +0 -59
package/lib/fetcher.js CHANGED
@@ -1,80 +1,68 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- var _typeof = require("@babel/runtime/helpers/typeof");
6
-
7
4
  Object.defineProperty(exports, "__esModule", {
8
5
  value: true
9
6
  });
10
7
  exports.default = void 0;
11
-
12
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
13
-
14
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
15
-
16
- var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
17
-
18
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
19
-
20
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
21
-
22
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
23
-
24
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
25
-
26
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
27
-
28
9
  var _store = _interopRequireDefault(require("./store"));
29
-
30
10
  var _log = _interopRequireDefault(require("./log"));
31
-
32
11
  var _n3parser = _interopRequireDefault(require("./n3parser"));
33
-
34
12
  var _namedNode = _interopRequireDefault(require("./named-node"));
35
-
36
13
  var _namespace = _interopRequireDefault(require("./namespace"));
37
-
38
14
  var _parse = _interopRequireDefault(require("./parse"));
39
-
40
15
  var _rdfaparser = require("./rdfaparser");
41
-
42
16
  var _rdfxmlparser = _interopRequireDefault(require("./rdfxmlparser"));
43
-
44
17
  var Uri = _interopRequireWildcard(require("./uri"));
45
-
46
18
  var _terms = require("./utils/terms");
47
-
48
19
  var Util = _interopRequireWildcard(require("./utils-js"));
49
-
50
20
  var _serialize = _interopRequireDefault(require("./serialize"));
51
-
52
21
  var _crossFetch = _interopRequireWildcard(require("cross-fetch"));
53
-
54
22
  var _types = require("./types");
55
-
56
23
  var _termValue = require("./utils/termValue");
57
-
58
24
  var _jsonldparser = _interopRequireDefault(require("./jsonldparser"));
25
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
27
+ /* global $SolidTestEnvironment */
28
+ /**
29
+ *
30
+ * Project: rdflib.js
31
+ *
32
+ * @file: fetcher.js
33
+ *
34
+ * Description: contains functions for requesting/fetching/retracting
35
+ * This implements quite a lot of the web architecture.
36
+ * A fetcher is bound to a specific quad store, into which
37
+ * it loads stuff and into which it writes its metadata
38
+ * @@ The metadata could be optionally a separate graph
39
+ *
40
+ * - implements semantics of HTTP headers, Internet Content Types
41
+ * - selects parsers for rdf/xml, n3, rdfa, grddl
42
+ *
43
+ * TO do:
44
+ * - Implement a runtime registry for parsers and serializers
45
+ * -
46
+ */
59
47
 
60
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
61
-
62
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
63
-
64
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
65
-
66
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
48
+ /**
49
+ * Things to test: callbacks on request, refresh, retract
50
+ * loading from HTTP, HTTPS, FTP, FILE, others?
51
+ * To do:
52
+ * Firing up a mail client for mid: (message:) URLs
53
+ */
67
54
 
68
- var Parsable = {
55
+ const Parsable = {
69
56
  'text/n3': true,
70
57
  'text/turtle': true,
71
58
  'application/rdf+xml': true,
72
59
  'application/xhtml+xml': true,
73
60
  'text/html': true,
74
61
  'application/ld+json': true
75
- }; // This is a minimal set to allow the use of damaged servers if necessary
62
+ };
76
63
 
77
- var CONTENT_TYPE_BY_EXT = {
64
+ // This is a minimal set to allow the use of damaged servers if necessary
65
+ const CONTENT_TYPE_BY_EXT = {
78
66
  'rdf': _types.RDFXMLContentType,
79
67
  'owl': _types.RDFXMLContentType,
80
68
  'n3': 'text/n3',
@@ -83,13 +71,14 @@ var CONTENT_TYPE_BY_EXT = {
83
71
  'acl': 'text/n3',
84
72
  'html': 'text/html',
85
73
  'xml': 'text/xml'
86
- }; // Convenience namespaces needed in this module.
74
+ };
75
+
76
+ // Convenience namespaces needed in this module.
87
77
  // These are deliberately not exported as the user application should
88
78
  // make its own list and not rely on the prefixes used here,
89
79
  // and not be tempted to add to them, and them clash with those of another
90
80
  // application.
91
-
92
- var getNS = function getNS(factory) {
81
+ const getNS = factory => {
93
82
  return {
94
83
  link: (0, _namespace.default)('http://www.w3.org/2007/ont/link#', factory),
95
84
  http: (0, _namespace.default)('http://www.w3.org/2007/ont/http#', factory),
@@ -101,520 +90,351 @@ var getNS = function getNS(factory) {
101
90
  ldp: (0, _namespace.default)('http://www.w3.org/ns/ldp#', factory)
102
91
  };
103
92
  };
104
-
105
- var ns = getNS();
106
- var Handler = /*#__PURE__*/(0, _createClass2.default)( // TODO: Document, type
107
- // TODO: Document, type
108
- function Handler(response, dom) {
109
- (0, _classCallCheck2.default)(this, Handler);
110
- (0, _defineProperty2.default)(this, "response", void 0);
111
- (0, _defineProperty2.default)(this, "dom", void 0);
112
- this.response = response; // The type assertion operator here might need to be removed.
113
-
114
- this.dom = dom;
115
- });
93
+ const ns = getNS();
94
+ class Handler {
95
+ // TODO: Document, type
96
+
97
+ // TODO: Document, type
98
+
99
+ constructor(response, dom) {
100
+ (0, _defineProperty2.default)(this, "response", void 0);
101
+ (0, _defineProperty2.default)(this, "dom", void 0);
102
+ this.response = response;
103
+ // The type assertion operator here might need to be removed.
104
+ this.dom = dom;
105
+ }
106
+ }
116
107
  (0, _defineProperty2.default)(Handler, "pattern", void 0);
117
-
118
- var RDFXMLHandler = /*#__PURE__*/function (_Handler) {
119
- (0, _inherits2.default)(RDFXMLHandler, _Handler);
120
-
121
- var _super = _createSuper(RDFXMLHandler);
122
-
123
- function RDFXMLHandler() {
124
- (0, _classCallCheck2.default)(this, RDFXMLHandler);
125
- return _super.apply(this, arguments);
108
+ class RDFXMLHandler extends Handler {
109
+ static toString() {
110
+ return 'RDFXMLHandler';
126
111
  }
127
-
128
- (0, _createClass2.default)(RDFXMLHandler, [{
129
- key: "parse",
130
- value: function parse(fetcher,
131
- /** An XML String */
132
- responseText,
133
- /** Requires .original */
134
- options) {
135
- var kb = fetcher.store;
136
-
137
- if (!this.dom) {
138
- this.dom = Util.parseXML(responseText);
139
- }
140
-
141
- var root = this.dom.documentElement;
142
-
143
- if (root.nodeName === 'parsererror') {
144
- // Mozilla only See issue/issue110
145
- // have to fail the request
146
- return fetcher.failFetch(options, 'Badly formed XML in ' + options.resource.value, 'parse_error');
147
- }
148
-
149
- var parser = new _rdfxmlparser.default(kb);
150
-
151
- try {
152
- parser.parse(this.dom, options.original.value, options.original);
153
- } catch (err) {
154
- return fetcher.failFetch(options, 'Syntax error parsing RDF/XML! ' + err, 'parse_error');
155
- }
156
-
157
- if (!options.noMeta) {
158
- kb.add(options.original, ns.rdf('type'), ns.link('RDFDocument'), fetcher.appNode);
159
- }
160
-
161
- return fetcher.doneFetch(options, this.response);
162
- }
163
- }], [{
164
- key: "toString",
165
- value: function toString() {
166
- return 'RDFXMLHandler';
167
- }
168
- }, {
169
- key: "register",
170
- value: function register(fetcher) {
171
- fetcher.mediatypes[_types.RDFXMLContentType] = {
172
- 'q': 0.9
173
- };
174
- }
175
- }]);
176
- return RDFXMLHandler;
177
- }(Handler);
178
-
112
+ static register(fetcher) {
113
+ fetcher.mediatypes[_types.RDFXMLContentType] = {
114
+ 'q': 0.9
115
+ };
116
+ }
117
+ parse(fetcher, /** An XML String */
118
+ responseText, /** Requires .original */
119
+ options) {
120
+ let kb = fetcher.store;
121
+ if (!this.dom) {
122
+ this.dom = Util.parseXML(responseText);
123
+ }
124
+ let root = this.dom.documentElement;
125
+ if (root.nodeName === 'parsererror') {
126
+ // Mozilla only See issue/issue110
127
+ // have to fail the request
128
+ return fetcher.failFetch(options, 'Badly formed XML in ' + options.resource.value, 'parse_error');
129
+ }
130
+ let parser = new _rdfxmlparser.default(kb);
131
+ try {
132
+ parser.parse(this.dom, options.original.value, options.original);
133
+ } catch (err) {
134
+ return fetcher.failFetch(options, 'Syntax error parsing RDF/XML! ' + err, 'parse_error');
135
+ }
136
+ if (!options.noMeta) {
137
+ kb.add(options.original, ns.rdf('type'), ns.link('RDFDocument'), fetcher.appNode);
138
+ }
139
+ return fetcher.doneFetch(options, this.response);
140
+ }
141
+ }
179
142
  RDFXMLHandler.pattern = new RegExp('application/rdf\\+xml');
180
-
181
- var XHTMLHandler = /*#__PURE__*/function (_Handler2) {
182
- (0, _inherits2.default)(XHTMLHandler, _Handler2);
183
-
184
- var _super2 = _createSuper(XHTMLHandler);
185
-
186
- function XHTMLHandler() {
187
- (0, _classCallCheck2.default)(this, XHTMLHandler);
188
- return _super2.apply(this, arguments);
143
+ class XHTMLHandler extends Handler {
144
+ static toString() {
145
+ return 'XHTMLHandler';
189
146
  }
190
-
191
- (0, _createClass2.default)(XHTMLHandler, [{
192
- key: "parse",
193
- value: function parse(fetcher, responseText, options) {
194
- var relation, reverse;
195
-
196
- if (!this.dom) {
197
- this.dom = Util.parseXML(responseText);
198
- }
199
-
200
- var kb = fetcher.store; // dc:title
201
-
202
- var title = this.dom.getElementsByTagName('title');
203
-
204
- if (title.length > 0) {
205
- kb.add(options.resource, ns.dc('title'), kb.rdfFactory.literal(title[0].textContent), options.resource); // log.info("Inferring title of " + xhr.resource)
206
- } // link rel
207
-
208
-
209
- var links = this.dom.getElementsByTagName('link');
210
-
211
- for (var x = links.length - 1; x >= 0; x--) {
212
- // @@ rev
213
- relation = links[x].getAttribute('rel');
214
- reverse = false;
215
-
216
- if (!relation) {
217
- relation = links[x].getAttribute('rev');
218
- reverse = true;
219
- }
220
-
221
- if (relation) {
222
- fetcher.linkData(options.original, relation, links[x].getAttribute('href'), options.resource, reverse);
223
- }
224
- } // Data Islands
225
-
226
-
227
- var scripts = this.dom.getElementsByTagName('script');
228
-
229
- for (var i = 0; i < scripts.length; i++) {
230
- var contentType = scripts[i].getAttribute('type');
231
-
232
- if (Parsable[contentType]) {
233
- // @ts-ignore incompatibility between Store.add and Formula.add
234
- (0, _parse.default)(scripts[i].textContent, kb, options.original.value, contentType); // @ts-ignore incompatibility between Store.add and Formula.add
235
-
236
- (0, _parse.default)(scripts[i].textContent, kb, options.original.value, contentType);
237
- }
147
+ static register(fetcher) {
148
+ fetcher.mediatypes[_types.XHTMLContentType] = {};
149
+ }
150
+ parse(fetcher, responseText, options) {
151
+ let relation, reverse;
152
+ if (!this.dom) {
153
+ this.dom = Util.parseXML(responseText);
154
+ }
155
+ let kb = fetcher.store;
156
+
157
+ // dc:title
158
+ let title = this.dom.getElementsByTagName('title');
159
+ if (title.length > 0) {
160
+ kb.add(options.resource, ns.dc('title'), kb.rdfFactory.literal(title[0].textContent), options.resource);
161
+ // log.info("Inferring title of " + xhr.resource)
162
+ }
163
+
164
+ // link rel
165
+ let links = this.dom.getElementsByTagName('link');
166
+ for (let x = links.length - 1; x >= 0; x--) {
167
+ // @@ rev
168
+ relation = links[x].getAttribute('rel');
169
+ reverse = false;
170
+ if (!relation) {
171
+ relation = links[x].getAttribute('rev');
172
+ reverse = true;
238
173
  }
239
-
240
- if (!options.noMeta) {
241
- kb.add(options.resource, ns.rdf('type'), ns.link('WebPage'), fetcher.appNode);
174
+ if (relation) {
175
+ fetcher.linkData(options.original, relation, links[x].getAttribute('href'), options.resource, reverse);
242
176
  }
177
+ }
243
178
 
244
- if (!options.noRDFa && _rdfaparser.parseRDFaDOM) {
245
- // enable by default
246
- try {
247
- (0, _rdfaparser.parseRDFaDOM)(this.dom, kb, options.original.value);
248
- } catch (err) {
249
- // @ts-ignore
250
- var msg = 'Error trying to parse ' + options.resource + ' as RDFa:\n' + err + ':\n' + err.stack;
251
- return fetcher.failFetch(options, msg, 'parse_error');
252
- }
179
+ // Data Islands
180
+ let scripts = this.dom.getElementsByTagName('script');
181
+ for (let i = 0; i < scripts.length; i++) {
182
+ let contentType = scripts[i].getAttribute('type');
183
+ if (Parsable[contentType]) {
184
+ // @ts-ignore incompatibility between Store.add and Formula.add
185
+ (0, _parse.default)(scripts[i].textContent, kb, options.original.value, contentType);
186
+ // @ts-ignore incompatibility between Store.add and Formula.add
187
+ (0, _parse.default)(scripts[i].textContent, kb, options.original.value, contentType);
253
188
  }
254
-
255
- return fetcher.doneFetch(options, this.response);
256
189
  }
257
- }], [{
258
- key: "toString",
259
- value: function toString() {
260
- return 'XHTMLHandler';
190
+ if (!options.noMeta) {
191
+ kb.add(options.resource, ns.rdf('type'), ns.link('WebPage'), fetcher.appNode);
261
192
  }
262
- }, {
263
- key: "register",
264
- value: function register(fetcher) {
265
- fetcher.mediatypes[_types.XHTMLContentType] = {};
193
+ if (!options.noRDFa && _rdfaparser.parseRDFaDOM) {
194
+ // enable by default
195
+ try {
196
+ (0, _rdfaparser.parseRDFaDOM)(this.dom, kb, options.original.value);
197
+ } catch (err) {
198
+ // @ts-ignore
199
+ let msg = 'Error trying to parse ' + options.resource + ' as RDFa:\n' + err + ':\n' + err.stack;
200
+ return fetcher.failFetch(options, msg, 'parse_error');
201
+ }
266
202
  }
267
- }]);
268
- return XHTMLHandler;
269
- }(Handler);
270
-
203
+ return fetcher.doneFetch(options, this.response);
204
+ }
205
+ }
271
206
  XHTMLHandler.pattern = new RegExp('application/xhtml');
272
-
273
- var XMLHandler = /*#__PURE__*/function (_Handler3) {
274
- (0, _inherits2.default)(XMLHandler, _Handler3);
275
-
276
- var _super3 = _createSuper(XMLHandler);
277
-
278
- function XMLHandler() {
279
- (0, _classCallCheck2.default)(this, XMLHandler);
280
- return _super3.apply(this, arguments);
207
+ class XMLHandler extends Handler {
208
+ static toString() {
209
+ return 'XMLHandler';
281
210
  }
282
-
283
- (0, _createClass2.default)(XMLHandler, [{
284
- key: "parse",
285
- value: function parse(fetcher, responseText, options) {
286
- var dom = Util.parseXML(responseText); // XML Semantics defined by root element namespace
287
- // figure out the root element
288
-
289
- for (var c = 0; c < dom.childNodes.length; c++) {
290
- var node = dom.childNodes[c]; // is this node an element?
291
-
292
- if (XMLHandler.isElement(node)) {
293
- // We've found the first element, it's the root
294
- var _ns = node.namespaceURI; // Is it RDF/XML?
295
-
296
- if (_ns && _ns === _ns['rdf']) {
297
- fetcher.addStatus(options.req, 'Has XML root element in the RDF namespace, so assume RDF/XML.');
298
- var rdfHandler = new RDFXMLHandler(this.response, dom);
299
- return rdfHandler.parse(fetcher, responseText, options);
300
- }
301
-
302
- break;
303
- }
304
- } // Or it could be XHTML?
305
- // Maybe it has an XHTML DOCTYPE?
306
-
307
-
308
- if (dom.doctype) {
309
- // log.info("We found a DOCTYPE in " + xhr.resource)
310
- if (dom.doctype.name === 'html' && dom.doctype.publicId.match(/^-\/\/W3C\/\/DTD XHTML/) && dom.doctype.systemId.match(/http:\/\/www.w3.org\/TR\/xhtml/)) {
311
- fetcher.addStatus(options.req, 'Has XHTML DOCTYPE. Switching to XHTML Handler.\n');
312
- var xhtmlHandler = new XHTMLHandler(this.response, dom);
313
- return xhtmlHandler.parse(fetcher, responseText, options);
314
- }
315
- } // Or what about an XHTML namespace?
316
-
317
-
318
- var html = dom.getElementsByTagName('html')[0];
319
-
320
- if (html) {
321
- var xmlns = html.getAttribute('xmlns');
322
-
323
- if (xmlns && xmlns.match(/^http:\/\/www.w3.org\/1999\/xhtml/)) {
324
- fetcher.addStatus(options.req, 'Has a default namespace for ' + 'XHTML. Switching to XHTMLHandler.\n');
325
-
326
- var _xhtmlHandler = new XHTMLHandler(this.response, dom);
327
-
328
- return _xhtmlHandler.parse(fetcher, responseText, options);
211
+ static register(fetcher) {
212
+ fetcher.mediatypes['text/xml'] = {
213
+ 'q': 0.5
214
+ };
215
+ fetcher.mediatypes['application/xml'] = {
216
+ 'q': 0.5
217
+ };
218
+ }
219
+ static isElement(node) {
220
+ return node.nodeType === Node.ELEMENT_NODE;
221
+ }
222
+ parse(fetcher, responseText, options) {
223
+ let dom = Util.parseXML(responseText);
224
+
225
+ // XML Semantics defined by root element namespace
226
+ // figure out the root element
227
+ for (let c = 0; c < dom.childNodes.length; c++) {
228
+ const node = dom.childNodes[c];
229
+ // is this node an element?
230
+ if (XMLHandler.isElement(node)) {
231
+ // We've found the first element, it's the root
232
+ let ns = node.namespaceURI;
233
+
234
+ // Is it RDF/XML?
235
+ if (ns && ns === ns['rdf']) {
236
+ fetcher.addStatus(options.req, 'Has XML root element in the RDF namespace, so assume RDF/XML.');
237
+ let rdfHandler = new RDFXMLHandler(this.response, dom);
238
+ return rdfHandler.parse(fetcher, responseText, options);
329
239
  }
330
- } // At this point we should check the namespace document (cache it!) and
331
- // look for a GRDDL transform
332
- // @@ Get namespace document <n>, parse it, look for <n> grddl:namespaceTransform ?y
333
- // Apply ?y to dom
334
- // We give up. What dialect is this?
335
-
336
-
337
- return fetcher.failFetch(options, 'Unsupported dialect of XML: not RDF or XHTML namespace, etc.\n' + responseText.slice(0, 80), 901);
338
- }
339
- }], [{
340
- key: "toString",
341
- value: function toString() {
342
- return 'XMLHandler';
343
- }
344
- }, {
345
- key: "register",
346
- value: function register(fetcher) {
347
- fetcher.mediatypes['text/xml'] = {
348
- 'q': 0.5
349
- };
350
- fetcher.mediatypes['application/xml'] = {
351
- 'q': 0.5
352
- };
353
- }
354
- }, {
355
- key: "isElement",
356
- value: function isElement(node) {
357
- return node.nodeType === Node.ELEMENT_NODE;
240
+ break;
241
+ }
358
242
  }
359
- }]);
360
- return XMLHandler;
361
- }(Handler);
362
-
363
- XMLHandler.pattern = new RegExp('(text|application)/(.*)xml');
364
-
365
- var HTMLHandler = /*#__PURE__*/function (_Handler4) {
366
- (0, _inherits2.default)(HTMLHandler, _Handler4);
367
-
368
- var _super4 = _createSuper(HTMLHandler);
369
-
370
- function HTMLHandler() {
371
- (0, _classCallCheck2.default)(this, HTMLHandler);
372
- return _super4.apply(this, arguments);
373
- }
374
-
375
- (0, _createClass2.default)(HTMLHandler, [{
376
- key: "parse",
377
- value: function parse(fetcher, responseText, options) {
378
- var kb = fetcher.store; // We only handle XHTML so we have to figure out if this is XML
379
- // log.info("Sniffing HTML " + xhr.resource + " for XHTML.")
380
243
 
381
- if (isXML(responseText)) {
382
- fetcher.addStatus(options.req, "Has an XML declaration. We'll assume " + "it's XHTML as the content-type was text/html.\n");
383
- var xhtmlHandler = new XHTMLHandler(this.response);
244
+ // Or it could be XHTML?
245
+ // Maybe it has an XHTML DOCTYPE?
246
+ if (dom.doctype) {
247
+ // log.info("We found a DOCTYPE in " + xhr.resource)
248
+ if (dom.doctype.name === 'html' && dom.doctype.publicId.match(/^-\/\/W3C\/\/DTD XHTML/) && dom.doctype.systemId.match(/http:\/\/www.w3.org\/TR\/xhtml/)) {
249
+ fetcher.addStatus(options.req, 'Has XHTML DOCTYPE. Switching to XHTML Handler.\n');
250
+ let xhtmlHandler = new XHTMLHandler(this.response, dom);
384
251
  return xhtmlHandler.parse(fetcher, responseText, options);
385
- } // DOCTYPE html
386
-
387
-
388
- if (isXHTML(responseText)) {
389
- fetcher.addStatus(options.req, 'Has XHTML DOCTYPE. Switching to XHTMLHandler.\n');
390
-
391
- var _xhtmlHandler2 = new XHTMLHandler(this.response);
392
-
393
- return _xhtmlHandler2.parse(fetcher, responseText, options);
394
- } // xmlns
395
-
396
-
397
- if (isXMLNS(responseText)) {
398
- fetcher.addStatus(options.req, 'Has default namespace for XHTML, so switching to XHTMLHandler.\n');
399
-
400
- var _xhtmlHandler3 = new XHTMLHandler(this.response);
401
-
402
- return _xhtmlHandler3.parse(fetcher, responseText, options);
403
- } // dc:title
404
- // no need to escape '/' here
405
-
406
-
407
- var titleMatch = new RegExp('<title>([\\s\\S]+?)</title>', 'im').exec(responseText);
408
-
409
- if (titleMatch) {
410
- kb.add(options.resource, ns.dc('title'), kb.rdfFactory.literal(titleMatch[1]), options.resource); // think about xml:lang later
411
252
  }
412
-
413
- kb.add(options.resource, ns.rdf('type'), ns.link('WebPage'), fetcher.appNode);
414
- fetcher.addStatus(options.req, 'non-XML HTML document, not parsed for data.');
415
- return fetcher.doneFetch(options, this.response);
416
- }
417
- }], [{
418
- key: "toString",
419
- value: function toString() {
420
- return 'HTMLHandler';
421
- }
422
- }, {
423
- key: "register",
424
- value: function register(fetcher) {
425
- fetcher.mediatypes['text/html'] = {
426
- 'q': 0.9
427
- };
428
253
  }
429
- }]);
430
- return HTMLHandler;
431
- }(Handler);
432
-
433
- HTMLHandler.pattern = new RegExp('text/html');
434
-
435
- var JsonLdHandler = /*#__PURE__*/function (_Handler5) {
436
- (0, _inherits2.default)(JsonLdHandler, _Handler5);
437
-
438
- var _super5 = _createSuper(JsonLdHandler);
439
-
440
- function JsonLdHandler() {
441
- (0, _classCallCheck2.default)(this, JsonLdHandler);
442
- return _super5.apply(this, arguments);
443
- }
444
-
445
- (0, _createClass2.default)(JsonLdHandler, [{
446
- key: "parse",
447
- value: function parse(fetcher, responseText, options, response) {
448
- var kb = fetcher.store;
449
- return new Promise(function (resolve, reject) {
450
- try {
451
- (0, _jsonldparser.default)(responseText, kb, options.original.value, function () {
452
- resolve(fetcher.doneFetch(options, response));
453
- });
454
- } catch (err) {
455
- var msg = 'Error trying to parse ' + options.resource + ' as JSON-LD:\n' + err; // not err.stack -- irrelevant
456
254
 
457
- resolve(fetcher.failFetch(options, msg, 'parse_error', response));
458
- }
459
- });
460
- }
461
- }], [{
462
- key: "toString",
463
- value: function toString() {
464
- return 'JsonLdHandler';
465
- }
466
- }, {
467
- key: "register",
468
- value: function register(fetcher) {
469
- fetcher.mediatypes['application/ld+json'] = {
470
- 'q': 0.9
471
- };
255
+ // Or what about an XHTML namespace?
256
+ let html = dom.getElementsByTagName('html')[0];
257
+ if (html) {
258
+ let xmlns = html.getAttribute('xmlns');
259
+ if (xmlns && xmlns.match(/^http:\/\/www.w3.org\/1999\/xhtml/)) {
260
+ fetcher.addStatus(options.req, 'Has a default namespace for ' + 'XHTML. Switching to XHTMLHandler.\n');
261
+ let xhtmlHandler = new XHTMLHandler(this.response, dom);
262
+ return xhtmlHandler.parse(fetcher, responseText, options);
263
+ }
472
264
  }
473
- }]);
474
- return JsonLdHandler;
475
- }(Handler);
476
-
477
- JsonLdHandler.pattern = /application\/ld\+json/;
478
-
479
- var TextHandler = /*#__PURE__*/function (_Handler6) {
480
- (0, _inherits2.default)(TextHandler, _Handler6);
481
265
 
482
- var _super6 = _createSuper(TextHandler);
483
-
484
- function TextHandler() {
485
- (0, _classCallCheck2.default)(this, TextHandler);
486
- return _super6.apply(this, arguments);
266
+ // At this point we should check the namespace document (cache it!) and
267
+ // look for a GRDDL transform
268
+ // @@ Get namespace document <n>, parse it, look for <n> grddl:namespaceTransform ?y
269
+ // Apply ?y to dom
270
+ // We give up. What dialect is this?
271
+ return fetcher.failFetch(options, 'Unsupported dialect of XML: not RDF or XHTML namespace, etc.\n' + responseText.slice(0, 80), 901);
487
272
  }
273
+ }
274
+ XMLHandler.pattern = new RegExp('(text|application)/(.*)xml');
275
+ class HTMLHandler extends Handler {
276
+ static toString() {
277
+ return 'HTMLHandler';
278
+ }
279
+ static register(fetcher) {
280
+ fetcher.mediatypes['text/html'] = {
281
+ 'q': 0.9
282
+ };
283
+ }
284
+ parse(fetcher, responseText, options) {
285
+ let kb = fetcher.store;
488
286
 
489
- (0, _createClass2.default)(TextHandler, [{
490
- key: "parse",
491
- value: function parse(fetcher, responseText, options) {
492
- // We only speak dialects of XML right now. Is this XML?
493
- // Look for an XML declaration
494
- if (isXML(responseText)) {
495
- fetcher.addStatus(options.req, 'Warning: ' + options.resource + " has an XML declaration. We'll assume " + "it's XML but its content-type wasn't XML.\n");
496
- var xmlHandler = new XMLHandler(this.response);
497
- return xmlHandler.parse(fetcher, responseText, options);
498
- } // Look for an XML declaration
499
-
500
-
501
- if (responseText.slice(0, 500).match(/xmlns:/)) {
502
- fetcher.addStatus(options.req, "May have an XML namespace. We'll assume " + "it's XML but its content-type wasn't XML.\n");
503
-
504
- var _xmlHandler = new XMLHandler(this.response);
505
-
506
- return _xmlHandler.parse(fetcher, responseText, options);
507
- } // We give up finding semantics - this is not an error, just no data
508
-
509
-
510
- fetcher.addStatus(options.req, 'Plain text document, no known RDF semantics.');
511
- return fetcher.doneFetch(options, this.response);
512
- }
513
- }], [{
514
- key: "toString",
515
- value: function toString() {
516
- return 'TextHandler';
287
+ // We only handle XHTML so we have to figure out if this is XML
288
+ // log.info("Sniffing HTML " + xhr.resource + " for XHTML.")
289
+ if (isXML(responseText)) {
290
+ fetcher.addStatus(options.req, "Has an XML declaration. We'll assume " + "it's XHTML as the content-type was text/html.\n");
291
+ let xhtmlHandler = new XHTMLHandler(this.response);
292
+ return xhtmlHandler.parse(fetcher, responseText, options);
517
293
  }
518
- }, {
519
- key: "register",
520
- value: function register(fetcher) {
521
- fetcher.mediatypes['text/plain'] = {
522
- 'q': 0.5
523
- };
524
- }
525
- }]);
526
- return TextHandler;
527
- }(Handler);
528
294
 
529
- TextHandler.pattern = new RegExp('text/plain');
295
+ // DOCTYPE html
296
+ if (isXHTML(responseText)) {
297
+ fetcher.addStatus(options.req, 'Has XHTML DOCTYPE. Switching to XHTMLHandler.\n');
298
+ let xhtmlHandler = new XHTMLHandler(this.response);
299
+ return xhtmlHandler.parse(fetcher, responseText, options);
300
+ }
530
301
 
531
- var N3Handler = /*#__PURE__*/function (_Handler7) {
532
- (0, _inherits2.default)(N3Handler, _Handler7);
302
+ // xmlns
303
+ if (isXMLNS(responseText)) {
304
+ fetcher.addStatus(options.req, 'Has default namespace for XHTML, so switching to XHTMLHandler.\n');
305
+ let xhtmlHandler = new XHTMLHandler(this.response);
306
+ return xhtmlHandler.parse(fetcher, responseText, options);
307
+ }
533
308
 
534
- var _super7 = _createSuper(N3Handler);
309
+ // dc:title
310
+ // no need to escape '/' here
311
+ let titleMatch = new RegExp('<title>([\\s\\S]+?)</title>', 'im').exec(responseText);
312
+ if (titleMatch) {
313
+ kb.add(options.resource, ns.dc('title'), kb.rdfFactory.literal(titleMatch[1]), options.resource); // think about xml:lang later
314
+ }
535
315
 
536
- function N3Handler() {
537
- (0, _classCallCheck2.default)(this, N3Handler);
538
- return _super7.apply(this, arguments);
316
+ kb.add(options.resource, ns.rdf('type'), ns.link('WebPage'), fetcher.appNode);
317
+ fetcher.addStatus(options.req, 'non-XML HTML document, not parsed for data.');
318
+ return fetcher.doneFetch(options, this.response);
539
319
  }
540
-
541
- (0, _createClass2.default)(N3Handler, [{
542
- key: "parse",
543
- value: function parse(fetcher, responseText, options, response) {
544
- // Parse the text of this N3 file
545
- var kb = fetcher.store;
546
- var p = (0, _n3parser.default)(kb, kb, options.original.value, options.original.value, null, null, '', null); // p.loadBuf(xhr.responseText)
547
-
320
+ }
321
+ HTMLHandler.pattern = new RegExp('text/html');
322
+ class JsonLdHandler extends Handler {
323
+ static toString() {
324
+ return 'JsonLdHandler';
325
+ }
326
+ static register(fetcher) {
327
+ fetcher.mediatypes['application/ld+json'] = {
328
+ 'q': 0.9
329
+ };
330
+ }
331
+ parse(fetcher, responseText, options, response) {
332
+ const kb = fetcher.store;
333
+ return new Promise((resolve, reject) => {
548
334
  try {
549
- p.loadBuf(responseText);
335
+ (0, _jsonldparser.default)(responseText, kb, options.original.value, () => {
336
+ resolve(fetcher.doneFetch(options, response));
337
+ });
550
338
  } catch (err) {
551
- var msg = 'Error trying to parse ' + options.resource + ' as Notation3:\n' + err; // not err.stack -- irrelevant
552
-
553
- return fetcher.failFetch(options, msg, 'parse_error', response);
339
+ const msg = 'Error trying to parse ' + options.resource + ' as JSON-LD:\n' + err; // not err.stack -- irrelevant
340
+ resolve(fetcher.failFetch(options, msg, 'parse_error', response));
554
341
  }
342
+ });
343
+ }
344
+ }
345
+ JsonLdHandler.pattern = /application\/ld\+json/;
346
+ class TextHandler extends Handler {
347
+ static toString() {
348
+ return 'TextHandler';
349
+ }
350
+ static register(fetcher) {
351
+ fetcher.mediatypes['text/plain'] = {
352
+ 'q': 0.5
353
+ };
354
+ }
355
+ parse(fetcher, responseText, options) {
356
+ // We only speak dialects of XML right now. Is this XML?
555
357
 
556
- fetcher.addStatus(options.req, 'N3 parsed: ' + p.statementCount + ' triples in ' + p.lines + ' lines.');
557
- fetcher.store.add(options.original, ns.rdf('type'), ns.link('RDFDocument'), fetcher.appNode);
558
- return fetcher.doneFetch(options, this.response);
358
+ // Look for an XML declaration
359
+ if (isXML(responseText)) {
360
+ fetcher.addStatus(options.req, 'Warning: ' + options.resource + " has an XML declaration. We'll assume " + "it's XML but its content-type wasn't XML.\n");
361
+ let xmlHandler = new XMLHandler(this.response);
362
+ return xmlHandler.parse(fetcher, responseText, options);
559
363
  }
560
- }], [{
561
- key: "toString",
562
- value: function toString() {
563
- return 'N3Handler';
564
- }
565
- }, {
566
- key: "register",
567
- value: function register(fetcher) {
568
- fetcher.mediatypes['text/n3'] = {
569
- 'q': '1.0'
570
- }; // as per 2008 spec
571
-
572
- /*
573
- fetcher.mediatypes['application/x-turtle'] = {
574
- 'q': 1.0
575
- } // pre 2008
576
- */
577
364
 
578
- fetcher.mediatypes['text/turtle'] = {
579
- 'q': 1.0
580
- }; // post 2008
365
+ // Look for an XML declaration
366
+ if (responseText.slice(0, 500).match(/xmlns:/)) {
367
+ fetcher.addStatus(options.req, "May have an XML namespace. We'll assume " + "it's XML but its content-type wasn't XML.\n");
368
+ let xmlHandler = new XMLHandler(this.response);
369
+ return xmlHandler.parse(fetcher, responseText, options);
581
370
  }
582
- }]);
583
- return N3Handler;
584
- }(Handler);
585
371
 
372
+ // We give up finding semantics - this is not an error, just no data
373
+ fetcher.addStatus(options.req, 'Plain text document, no known RDF semantics.');
374
+ return fetcher.doneFetch(options, this.response);
375
+ }
376
+ }
377
+ TextHandler.pattern = new RegExp('text/plain');
378
+ class N3Handler extends Handler {
379
+ static toString() {
380
+ return 'N3Handler';
381
+ }
382
+ static register(fetcher) {
383
+ fetcher.mediatypes['text/n3'] = {
384
+ 'q': '1.0'
385
+ }; // as per 2008 spec
386
+ /*
387
+ fetcher.mediatypes['application/x-turtle'] = {
388
+ 'q': 1.0
389
+ } // pre 2008
390
+ */
391
+ fetcher.mediatypes['text/turtle'] = {
392
+ 'q': 1.0
393
+ }; // post 2008
394
+ }
395
+
396
+ parse(fetcher, responseText, options, response) {
397
+ // Parse the text of this N3 file
398
+ let kb = fetcher.store;
399
+ let p = (0, _n3parser.default)(kb, kb, options.original.value, options.original.value, null, null, '', null);
400
+ // p.loadBuf(xhr.responseText)
401
+ try {
402
+ p.loadBuf(responseText);
403
+ } catch (err) {
404
+ let msg = 'Error trying to parse ' + options.resource + ' as Notation3:\n' + err; // not err.stack -- irrelevant
405
+ return fetcher.failFetch(options, msg, 'parse_error', response);
406
+ }
407
+ fetcher.addStatus(options.req, 'N3 parsed: ' + p.statementCount + ' triples in ' + p.lines + ' lines.');
408
+ fetcher.store.add(options.original, ns.rdf('type'), ns.link('RDFDocument'), fetcher.appNode);
409
+ return fetcher.doneFetch(options, this.response);
410
+ }
411
+ }
586
412
  N3Handler.pattern = new RegExp('(application|text)/(x-)?(rdf\\+)?(n3|turtle)');
587
- var defaultHandlers = {
588
- RDFXMLHandler: RDFXMLHandler,
589
- XHTMLHandler: XHTMLHandler,
590
- XMLHandler: XMLHandler,
591
- HTMLHandler: HTMLHandler,
592
- TextHandler: TextHandler,
593
- N3Handler: N3Handler,
594
- JsonLdHandler: JsonLdHandler
413
+ const defaultHandlers = {
414
+ RDFXMLHandler,
415
+ XHTMLHandler,
416
+ XMLHandler,
417
+ HTMLHandler,
418
+ TextHandler,
419
+ N3Handler,
420
+ JsonLdHandler
595
421
  };
596
-
597
422
  function isXHTML(responseText) {
598
- var docTypeStart = responseText.indexOf('<!DOCTYPE html');
599
- var docTypeEnd = responseText.indexOf('>');
600
-
423
+ const docTypeStart = responseText.indexOf('<!DOCTYPE html');
424
+ const docTypeEnd = responseText.indexOf('>');
601
425
  if (docTypeStart === -1 || docTypeEnd === -1 || docTypeStart > docTypeEnd) {
602
426
  return false;
603
427
  }
604
-
605
428
  return responseText.substr(docTypeStart, docTypeEnd - docTypeStart).indexOf('XHTML') !== -1;
606
429
  }
607
-
608
430
  function isXML(responseText) {
609
- var match = responseText.match(/\s*<\?xml\s+version\s*=[^<>]+\?>/);
431
+ const match = responseText.match(/\s*<\?xml\s+version\s*=[^<>]+\?>/);
610
432
  return !!match;
611
433
  }
612
-
613
434
  function isXMLNS(responseText) {
614
- var match = responseText.match(/[^(<html)]*<html\s+[^<]*xmlns=['"]http:\/\/www.w3.org\/1999\/xhtml["'][^<]*>/);
435
+ const match = responseText.match(/[^(<html)]*<html\s+[^<]*xmlns=['"]http:\/\/www.w3.org\/1999\/xhtml["'][^<]*>/);
615
436
  return !!match;
616
437
  }
617
-
618
438
  /** Fetcher
619
439
  *
620
440
  * The Fetcher object is a helper object for a quadstore
@@ -623,7 +443,7 @@ function isXMLNS(responseText) {
623
443
  * figuring how to parse them. It will also refresh, remove, the data
624
444
  * and put back the data to the web.
625
445
  */
626
- var Fetcher = /*#__PURE__*/function () {
446
+ class Fetcher {
627
447
  /** Denoting this session */
628
448
 
629
449
  /**
@@ -647,14 +467,13 @@ var Fetcher = /*#__PURE__*/function () {
647
467
  /** fetchCallbacks[uri].push(callback) */
648
468
 
649
469
  /** Keep track of explicit 404s -> we can overwrite etc */
470
+
650
471
  // TODO: Document this
651
472
 
652
473
  /** Methods added by calling Util.callbackify in the constructor*/
653
- function Fetcher(store) {
654
- var _this = this;
655
474
 
656
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
657
- (0, _classCallCheck2.default)(this, Fetcher);
475
+ constructor(store) {
476
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
658
477
  (0, _defineProperty2.default)(this, "store", void 0);
659
478
  (0, _defineProperty2.default)(this, "timeout", void 0);
660
479
  (0, _defineProperty2.default)(this, "_fetch", void 0);
@@ -672,17 +491,15 @@ var Fetcher = /*#__PURE__*/function () {
672
491
  (0, _defineProperty2.default)(this, "fireCallbacks", void 0);
673
492
  this.store = store || new _store.default();
674
493
  this.ns = getNS(this.store.rdfFactory);
675
- this.timeout = options.timeout || 30000; // solidFetcher is deprecated
494
+ this.timeout = options.timeout || 30000;
676
495
 
496
+ // solidFetcher is deprecated
677
497
  this._fetch = options.fetch || typeof global !== 'undefined' && (global.solidFetcher || global.solidFetch) || typeof window !== 'undefined' && (window.solidFetcher || window.solidFetch) || _crossFetch.default;
678
-
679
498
  if (!this._fetch) {
680
499
  throw new Error('No _fetch function available for Fetcher');
681
500
  }
682
-
683
501
  this.appNode = this.store.rdfFactory.blankNode();
684
502
  this.store.fetcher = this; // Bi-linked
685
-
686
503
  this.requested = {};
687
504
  this.timeouts = {};
688
505
  this.redirectedTo = {};
@@ -698,258 +515,279 @@ var Fetcher = /*#__PURE__*/function () {
698
515
  '*/*': {
699
516
  'q': 0.1
700
517
  } // Must allow access to random content
518
+ };
701
519
 
702
- }; // Util.callbackify(this, ['request', 'recv', 'headers', 'load', 'fail',
520
+ // Util.callbackify(this, ['request', 'recv', 'headers', 'load', 'fail',
703
521
  // 'refresh', 'retract', 'done'])
704
522
  // In switching to fetch(), 'recv', 'headers' and 'load' do not make sense
705
-
706
523
  Util.callbackify(this, ['request', 'fail', 'refresh', 'retract', 'done']);
707
- Object.keys(options.handlers || defaultHandlers).map(function (key) {
708
- return _this.addHandler(defaultHandlers[key]);
709
- });
524
+ Object.keys(options.handlers || defaultHandlers).map(key => this.addHandler(defaultHandlers[key]));
710
525
  }
711
-
712
- (0, _createClass2.default)(Fetcher, [{
713
- key: "load",
714
- value:
715
- /**
716
- * Promise-based load function
717
- *
718
- * Loads a web resource or resources into the store.
719
- *
720
- * A resource may be given as NamedNode object, or as a plain URI.
721
- * an array of resources will be given, in which they will be fetched in parallel.
722
- * By default, the HTTP headers are recorded also, in the same store, in a separate graph.
723
- * This allows code like editable() for example to test things about the resource.
724
- *
725
- * @param uri {Array<RDFlibNamedNode>|Array<string>|RDFlibNamedNode|string}
726
- *
727
- * @param [options={}] {Object}
728
- *
729
- * @param [options.fetch] {Function}
730
- *
731
- * @param [options.referringTerm] {RDFlibNamedNode} Referring term, the resource which
732
- * referred to this (for tracking bad links)
733
- *
734
- * @param [options.contentType] {string} Provided content type (for writes)
735
- *
736
- * @param [options.forceContentType] {string} Override the incoming header to
737
- * force the data to be treated as this content-type (for reads)
738
- *
739
- * @param [options.force] {boolean} Load the data even if loaded before.
740
- * Also sets the `Cache-Control:` header to `no-cache`
741
- *
742
- * @param [options.baseURI=docuri] {Node|string} Original uri to preserve
743
- * through proxying etc (`xhr.original`).
744
- *
745
- * @param [options.proxyUsed] {boolean} Whether this request is a retry via
746
- * a proxy (generally done from an error handler)
747
- *
748
- * @param [options.withCredentials] {boolean} flag for XHR/CORS etc
749
- *
750
- * @param [options.clearPreviousData] {boolean} Before we parse new data,
751
- * clear old, but only on status 200 responses
752
- *
753
- * @param [options.noMeta] {boolean} Prevents the addition of various metadata
754
- * triples (about the fetch request) to the store
755
- *
756
- * @param [options.noRDFa] {boolean}
757
- *
758
- * @returns {Promise<Result>}
759
- */
760
- function load(uri) {
761
- var _this2 = this;
762
-
763
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
764
- options = Object.assign({}, options); // Take a copy as we add stuff to the options!!
765
-
766
- if (uri instanceof Array) {
767
- return Promise.all(uri.map(function (x) {
768
- return _this2.load(x, Object.assign({}, options));
769
- }));
770
- }
771
-
772
- var uriIn = uri;
773
- var docuri = (0, _termValue.termValue)(uriIn);
774
- docuri = docuri.split('#')[0];
775
- options = this.initFetchOptions(docuri, options);
776
- var initialisedOptions = this.initFetchOptions(docuri, options);
777
- return this.pendingFetchPromise(docuri, initialisedOptions.baseURI, initialisedOptions);
526
+ static crossSiteProxy(uri) {
527
+ if (Fetcher.crossSiteProxyTemplate) {
528
+ return Fetcher.crossSiteProxyTemplate.replace('{uri}', encodeURIComponent(uri));
529
+ } else {
530
+ return undefined;
778
531
  }
779
- }, {
780
- key: "pendingFetchPromise",
781
- value: function pendingFetchPromise(uri, originalUri, options) {
782
- var _this3 = this;
783
-
784
- var pendingPromise; // Check to see if some request is already dealing with this uri
785
-
786
- if (!options.force && this.fetchQueue[originalUri]) {
787
- pendingPromise = this.fetchQueue[originalUri];
532
+ }
533
+ static offlineOverride(uri) {
534
+ // Map the URI to a localhost proxy if we are running on localhost
535
+ // This is used for working offline, e.g. on planes.
536
+ // Is the script itself is running in localhost, then access all
537
+ // data in a localhost mirror.
538
+ // Do not remove without checking with TimBL
539
+ let requestedURI = uri;
540
+ var UI;
541
+ if (typeof window !== 'undefined' && window.panes && (UI = window.panes.UI) && UI.preferences && UI.preferences.get('offlineModeUsingLocalhost')) {
542
+ if (requestedURI.slice(0, 7) === 'http://' && requestedURI.slice(7, 17) !== 'localhost/') {
543
+ requestedURI = 'http://localhost/' + requestedURI.slice(7);
544
+ _log.default.warn('Localhost kludge for offline use: actually getting <' + requestedURI + '>');
788
545
  } else {
789
- pendingPromise = Promise.race([this.setRequestTimeout(uri, options), this.fetchUri(uri, options)]);
790
- this.fetchQueue[originalUri] = pendingPromise; // Clean up the queued promise after a time, if it's resolved
791
-
792
- this.cleanupFetchRequest(originalUri, undefined, this.timeout);
546
+ // log.warn("Localhost kludge NOT USED <" + requestedURI + ">")
793
547
  }
548
+ } else {
549
+ // log.warn("Localhost kludge OFF offline use: actually getting <" +
550
+ // requestedURI + ">")
551
+ }
552
+ return requestedURI;
553
+ }
554
+ static proxyIfNecessary(uri) {
555
+ var UI;
556
+ if (typeof window !== 'undefined' && window.panes && (UI = window.panes.UI) && UI.isExtension) {
557
+ return uri;
558
+ } // Extension does not need proxy
794
559
 
795
- return pendingPromise.then(function (x) {
796
- if (uri in _this3.timeouts) {
797
- _this3.timeouts[uri].forEach(clearTimeout);
560
+ if (typeof $SolidTestEnvironment !== 'undefined' && $SolidTestEnvironment.localSiteMap) {
561
+ // nested dictionaries of URI parts from origin down
562
+ let hostpath = uri.split('/').slice(2); // the bit after the //
798
563
 
799
- delete _this3.timeouts[uri];
564
+ const lookup = (parts, index) => {
565
+ let z = index[parts.shift()];
566
+ if (!z) {
567
+ return null;
568
+ }
569
+ if (typeof z === 'string') {
570
+ return z + parts.join('/');
800
571
  }
572
+ if (!parts) {
573
+ return null;
574
+ }
575
+ return lookup(parts, z);
576
+ };
577
+ const y = lookup(hostpath, $SolidTestEnvironment.localSiteMap);
578
+ if (y) {
579
+ return y;
580
+ }
581
+ }
801
582
 
802
- return x;
803
- });
583
+ // browser does 2014 on as https browser script not trusted
584
+ // If the web app origin is https: then the mixed content rules
585
+ // prevent it loading insecure http: stuff so we need proxy.
586
+ if (Fetcher.crossSiteProxyTemplate && typeof document !== 'undefined' && document.location && ('' + document.location).slice(0, 6) === 'https:' &&
587
+ // origin is secure
588
+ uri.slice(0, 5) === 'http:') {
589
+ // requested data is not
590
+ return Fetcher.crossSiteProxyTemplate.replace('{uri}', encodeURIComponent(uri));
804
591
  }
805
- /**
806
- * @param _options - DEPRECATED
807
- */
592
+ return uri;
593
+ }
808
594
 
809
- }, {
810
- key: "cleanupFetchRequest",
811
- value: function cleanupFetchRequest(originalUri, _options, timeout) {
812
- var _this4 = this;
595
+ /**
596
+ * Tests whether the uri's protocol is supported by the Fetcher.
597
+ * @param uri
598
+ */
599
+ static unsupportedProtocol(uri) {
600
+ let pcol = Uri.protocol(uri);
601
+ return pcol === 'tel' || pcol === 'mailto' || pcol === 'urn';
602
+ }
813
603
 
814
- if (_options !== undefined) {
815
- console.warn("_options is deprecated");
604
+ /** Decide on credentials using old XXHR api or new fetch() one
605
+ * @param requestedURI
606
+ * @param options
607
+ */
608
+ static setCredentials(requestedURI) {
609
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
610
+ // 2014 CORS problem:
611
+ // XMLHttpRequest cannot load http://www.w3.org/People/Berners-Lee/card.
612
+ // A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin'
613
+ // header when the credentials flag is true.
614
+ // @ Many ontology files under http: and need CORS wildcard ->
615
+ // can't have credentials
616
+ if (options.credentials === undefined) {
617
+ // Caller using new fetch convention
618
+ if (options.withCredentials !== undefined) {
619
+ // XHR style is what Fetcher specified before
620
+ options.credentials = options.withCredentials ? 'include' : 'omit';
621
+ } else {
622
+ options.credentials = 'include'; // default is to be logged on
816
623
  }
817
-
818
- this.timeouts[originalUri] = (this.timeouts[originalUri] || []).concat(setTimeout(function () {
819
- if (!_this4.isPending(originalUri)) {
820
- delete _this4.fetchQueue[originalUri];
821
- }
822
- }, timeout));
823
624
  }
824
- }, {
825
- key: "initFetchOptions",
826
- value: function initFetchOptions(uri, options) {
827
- var kb = this.store;
828
- var isGet = !options.method || options.method.toUpperCase() === 'GET';
829
-
830
- if (!isGet) {
831
- options.force = true;
832
- }
833
-
834
- options.resource = kb.rdfFactory.namedNode(uri); // This might be proxified
835
-
836
- options.baseURI = options.baseURI || uri; // Preserve though proxying etc
837
-
838
- options.original = kb.rdfFactory.namedNode(options.baseURI);
839
- options.req = kb.bnode();
840
- options.headers = options.headers || new _crossFetch.Headers();
841
-
842
- if (options.contentType) {
843
- // @ts-ignore
844
- options.headers['content-type'] = options.contentType;
845
- }
846
-
847
- if (options.force) {
848
- options.cache = 'no-cache';
849
- }
850
-
851
- var acceptString = this.acceptString(); // @ts-ignore
852
-
853
- options.headers['accept'] = acceptString;
854
- var requestedURI = Fetcher.offlineOverride(uri);
855
- options.requestedURI = requestedURI;
856
- Fetcher.setCredentials(requestedURI, options);
857
- var actualProxyURI = Fetcher.proxyIfNecessary(requestedURI);
858
-
859
- if (requestedURI !== actualProxyURI) {
860
- options.proxyUsed = true;
861
- }
625
+ }
862
626
 
863
- options.actualProxyURI = actualProxyURI;
864
- return options;
627
+ /**
628
+ * Promise-based load function
629
+ *
630
+ * Loads a web resource or resources into the store.
631
+ *
632
+ * A resource may be given as NamedNode object, or as a plain URI.
633
+ * an array of resources will be given, in which they will be fetched in parallel.
634
+ * By default, the HTTP headers are recorded also, in the same store, in a separate graph.
635
+ * This allows code like editable() for example to test things about the resource.
636
+ *
637
+ * @param uri {Array<RDFlibNamedNode>|Array<string>|RDFlibNamedNode|string}
638
+ *
639
+ * @param [options={}] {Object}
640
+ *
641
+ * @param [options.fetch] {Function}
642
+ *
643
+ * @param [options.referringTerm] {RDFlibNamedNode} Referring term, the resource which
644
+ * referred to this (for tracking bad links)
645
+ *
646
+ * @param [options.contentType] {string} Provided content type (for writes)
647
+ *
648
+ * @param [options.forceContentType] {string} Override the incoming header to
649
+ * force the data to be treated as this content-type (for reads)
650
+ *
651
+ * @param [options.force] {boolean} Load the data even if loaded before.
652
+ * Also sets the `Cache-Control:` header to `no-cache`
653
+ *
654
+ * @param [options.baseURI=docuri] {Node|string} Original uri to preserve
655
+ * through proxying etc (`xhr.original`).
656
+ *
657
+ * @param [options.proxyUsed] {boolean} Whether this request is a retry via
658
+ * a proxy (generally done from an error handler)
659
+ *
660
+ * @param [options.withCredentials] {boolean} flag for XHR/CORS etc
661
+ *
662
+ * @param [options.clearPreviousData] {boolean} Before we parse new data,
663
+ * clear old, but only on status 200 responses
664
+ *
665
+ * @param [options.noMeta] {boolean} Prevents the addition of various metadata
666
+ * triples (about the fetch request) to the store
667
+ *
668
+ * @param [options.noRDFa] {boolean}
669
+ *
670
+ * @returns {Promise<Result>}
671
+ */
672
+ load(uri) {
673
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
674
+ options = Object.assign({}, options); // Take a copy as we add stuff to the options!!
675
+ if (uri instanceof Array) {
676
+ return Promise.all(uri.map(x => {
677
+ return this.load(x, Object.assign({}, options));
678
+ }));
865
679
  }
866
- /**
867
- * (The promise chain ends in either a `failFetch()` or a `doneFetch()`)
868
- *
869
- * @param docuri {string}
870
- * @param options {Object}
871
- *
872
- * @returns {Promise<Object>} fetch() result or an { error, status } object
873
- */
874
-
875
- }, {
876
- key: "fetchUri",
877
- value: function fetchUri(docuri, options) {
878
- var _this5 = this;
879
-
880
- if (!docuri) {
881
- return Promise.reject(new Error('Cannot fetch an empty uri'));
882
- }
883
-
884
- if (Fetcher.unsupportedProtocol(docuri)) {
885
- return this.failFetch(options, 'fetcher: Unsupported protocol', 'unsupported_protocol');
680
+ const uriIn = uri;
681
+ let docuri = (0, _termValue.termValue)(uriIn);
682
+ docuri = docuri.split('#')[0];
683
+ options = this.initFetchOptions(docuri, options);
684
+ const initialisedOptions = this.initFetchOptions(docuri, options);
685
+ return this.pendingFetchPromise(docuri, initialisedOptions.baseURI, initialisedOptions);
686
+ }
687
+ async pendingFetchPromise(uri, originalUri, options) {
688
+ let pendingPromise;
689
+
690
+ // Check to see if some request is already dealing with this uri
691
+ if (!options.force && (await this.fetchQueue[originalUri])) {
692
+ pendingPromise = this.fetchQueue[originalUri];
693
+ } else {
694
+ pendingPromise = Promise.race([this.setRequestTimeout(uri, options), this.fetchUri(uri, options)]);
695
+ this.fetchQueue[originalUri] = pendingPromise;
696
+
697
+ // Clean up the queued promise after a time, if it's resolved
698
+ this.cleanupFetchRequest(originalUri, undefined, this.timeout);
699
+ }
700
+ return pendingPromise.then(x => {
701
+ if (uri in this.timeouts) {
702
+ this.timeouts[uri].forEach(clearTimeout);
703
+ delete this.timeouts[uri];
886
704
  }
705
+ return x;
706
+ });
707
+ }
887
708
 
888
- var state = this.getState(docuri);
889
-
890
- if (!options.force) {
891
- if (state === 'fetched') {
892
- // URI already fetched and added to store
893
- return Promise.resolve( // @ts-ignore This is not a valid response object
894
- this.doneFetch(options, {
895
- status: 200,
896
- ok: true,
897
- statusText: 'Already loaded into quadstore.'
898
- }));
899
- }
900
-
901
- if (state === 'failed' && this.requested[docuri] === 404) {
902
- // Remember nonexistence
903
- var _message = 'Previously failed: ' + this.requested[docuri]; // @ts-ignore This is not a valid response object
904
-
905
-
906
- var dummyResponse = {
907
- url: docuri,
908
- // This does not comply to Fetch spec, it can be a string value in rdflib
909
- status: this.requested[docuri],
910
- statusText: _message,
911
- responseText: _message,
912
- headers: new _crossFetch.Headers(),
913
- // Headers() ???
914
- ok: false,
915
- body: null,
916
- bodyUsed: false,
917
- size: 0,
918
- timeout: 0
919
- };
920
- return this.failFetch(options, _message, this.requested[docuri], dummyResponse);
921
- }
922
- } else {
923
- // options.force == true
924
- delete this.nonexistent[docuri];
709
+ /**
710
+ * @param _options - DEPRECATED
711
+ */
712
+ cleanupFetchRequest(originalUri, _options, timeout) {
713
+ if (_options !== undefined) {
714
+ console.warn("_options is deprecated");
715
+ }
716
+ this.timeouts[originalUri] = (this.timeouts[originalUri] || []).concat(setTimeout(() => {
717
+ if (!this.isPending(originalUri)) {
718
+ delete this.fetchQueue[originalUri];
925
719
  }
720
+ }, timeout));
721
+ }
722
+ initFetchOptions(uri, options) {
723
+ let kb = this.store;
724
+ let isGet = !options.method || options.method.toUpperCase() === 'GET';
725
+ if (!isGet) {
726
+ options.force = true;
727
+ }
728
+ options.resource = kb.rdfFactory.namedNode(uri); // This might be proxified
729
+ options.baseURI = options.baseURI || uri; // Preserve though proxying etc
730
+ options.original = kb.rdfFactory.namedNode(options.baseURI);
731
+ options.req = kb.bnode();
732
+ options.headers = options.headers || new _crossFetch.Headers();
733
+ if (options.contentType) {
734
+ // @ts-ignore
735
+ options.headers['content-type'] = options.contentType;
736
+ }
737
+ if (options.force) {
738
+ options.cache = 'no-cache';
739
+ }
740
+ let acceptString = this.acceptString();
741
+ // @ts-ignore
742
+ options.headers['accept'] = acceptString;
743
+ let requestedURI = Fetcher.offlineOverride(uri);
744
+ options.requestedURI = requestedURI;
745
+ Fetcher.setCredentials(requestedURI, options);
746
+ let actualProxyURI = Fetcher.proxyIfNecessary(requestedURI);
747
+ if (requestedURI !== actualProxyURI) {
748
+ options.proxyUsed = true;
749
+ }
750
+ options.actualProxyURI = actualProxyURI;
751
+ return options;
752
+ }
926
753
 
927
- this.fireCallbacks('request', [docuri]);
928
- this.requested[docuri] = true; // mark this uri as 'requested'
929
-
930
- if (!options.noMeta) {
931
- this.saveRequestMetadata(docuri, options);
754
+ /**
755
+ * (The promise chain ends in either a `failFetch()` or a `doneFetch()`)
756
+ *
757
+ * @param docuri {string}
758
+ * @param options {Object}
759
+ *
760
+ * @returns {Promise<Object>} fetch() result or an { error, status } object
761
+ */
762
+ fetchUri(docuri, options) {
763
+ if (!docuri) {
764
+ return Promise.reject(new Error('Cannot fetch an empty uri'));
765
+ }
766
+ if (Fetcher.unsupportedProtocol(docuri)) {
767
+ return this.failFetch(options, 'fetcher: Unsupported protocol', 'unsupported_protocol');
768
+ }
769
+ let state = this.getState(docuri);
770
+ if (!options.force) {
771
+ if (state === 'fetched') {
772
+ // URI already fetched and added to store
773
+ return Promise.resolve(
774
+ // @ts-ignore This is not a valid response object
775
+ this.doneFetch(options, {
776
+ status: 200,
777
+ ok: true,
778
+ statusText: 'Already loaded into quadstore.'
779
+ }));
932
780
  }
933
-
934
- var actualProxyURI = options.actualProxyURI; // Map might get mistakenly added into headers
935
- // error TS2339: Property 'map' does not exist on type 'Headers'.
936
-
937
- /* let map
938
- if (options.headers && map in options.headers) {
939
- delete options.headers.map
940
- } */
941
-
942
- return this._fetch(actualProxyURI, options).then(function (response) {
943
- return _this5.handleResponse(response, docuri, options);
944
- }, function (error) {
945
- // @@ handleError?
946
- // @ts-ignore Invalid response object
947
- var dummyResponse = {
948
- url: actualProxyURI,
949
- status: 999,
950
- // @@ what number/string should fetch failures report?
951
- statusText: (error.name || 'network failure') + ': ' + (error.errno || error.code || error.type),
952
- responseText: error.message,
781
+ if (state === 'failed' && this.requested[docuri] === 404) {
782
+ // Remember nonexistence
783
+ let message = 'Previously failed: ' + this.requested[docuri];
784
+ // @ts-ignore This is not a valid response object
785
+ let dummyResponse = {
786
+ url: docuri,
787
+ // This does not comply to Fetch spec, it can be a string value in rdflib
788
+ status: this.requested[docuri],
789
+ statusText: message,
790
+ responseText: message,
953
791
  headers: new _crossFetch.Headers(),
954
792
  // Headers() ???
955
793
  ok: false,
@@ -958,1197 +796,886 @@ var Fetcher = /*#__PURE__*/function () {
958
796
  size: 0,
959
797
  timeout: 0
960
798
  };
961
- console.log('Fetcher: <' + actualProxyURI + '> Non-HTTP fetch exception: ' + error);
962
- return _this5.handleError(dummyResponse, docuri, options); // possible credentials retry
963
- // return this.failFetch(options, 'fetch failed: ' + error, 999, dummyResponse) // Fake status code: fetch exception
964
- // handleError expects a response so we fake some important bits.
965
-
966
- /*
967
- this.handleError(, docuri, options)
968
- */
969
- });
970
- }
971
- /**
972
- * Asks for a doc to be loaded if necessary then calls back
973
- *
974
- * Calling methods:
975
- * nowOrWhenFetched (uri, userCallback)
976
- * nowOrWhenFetched (uri, options, userCallback)
977
- * nowOrWhenFetched (uri, referringTerm, userCallback, options) <-- old
978
- * nowOrWhenFetched (uri, referringTerm, userCallback) <-- old
979
- *
980
- * Options include:
981
- * referringTerm The document in which this link was found.
982
- * this is valuable when finding the source of bad URIs
983
- * force boolean. Never mind whether you have tried before,
984
- * load this from scratch.
985
- * forceContentType Override the incoming header to force the data to be
986
- * treated as this content-type.
987
- *
988
- * Callback function takes:
989
- *
990
- * ok True if the fetch worked, and got a 200 response.
991
- * False if any error happened
992
- *
993
- * errmessage Text error message if not OK.
994
- *
995
- * response The fetch Response object (was: XHR) if there was was one
996
- * includes response.status as the HTTP status if any.
997
- */
998
-
999
- }, {
1000
- key: "nowOrWhenFetched",
1001
- value: function nowOrWhenFetched(uriIn, p2, userCallback) {
1002
- var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1003
- var uri = (0, _termValue.termValue)(uriIn);
1004
-
1005
- if (typeof p2 === 'function') {
1006
- // nowOrWhenFetched (uri, userCallback)
1007
- userCallback = p2;
1008
- } else if (typeof p2 === 'undefined') {// original calling signature
1009
- // referringTerm = undefined
1010
- } else if ((0, _terms.isNamedNode)(p2)) {
1011
- // referringTerm = p2
1012
- options.referringTerm = p2;
1013
- } else {
1014
- // nowOrWhenFetched (uri, options, userCallback)
1015
- options = p2;
799
+ return this.failFetch(options, message, this.requested[docuri], dummyResponse);
1016
800
  }
801
+ } else {
802
+ // options.force == true
803
+ delete this.nonexistent[docuri];
804
+ }
805
+ this.fireCallbacks('request', [docuri]);
806
+ this.requested[docuri] = true; // mark this uri as 'requested'
807
+
808
+ if (!options.noMeta) {
809
+ this.saveRequestMetadata(docuri, options);
810
+ }
811
+ let {
812
+ actualProxyURI
813
+ } = options;
814
+
815
+ // Map might get mistakenly added into headers
816
+ // error TS2339: Property 'map' does not exist on type 'Headers'.
817
+ /* let map
818
+ if (options.headers && map in options.headers) {
819
+ delete options.headers.map
820
+ } */
821
+
822
+ return this._fetch(actualProxyURI, options).then(response => this.handleResponse(response, docuri, options), error => {
823
+ // @@ handleError?
824
+ // @ts-ignore Invalid response object
825
+ let dummyResponse = {
826
+ url: actualProxyURI,
827
+ status: 999,
828
+ // @@ what number/string should fetch failures report?
829
+ statusText: (error.name || 'network failure') + ': ' + (error.errno || error.code || error.type),
830
+ responseText: error.message,
831
+ headers: new _crossFetch.Headers(),
832
+ // Headers() ???
833
+ ok: false,
834
+ body: null,
835
+ bodyUsed: false,
836
+ size: 0,
837
+ timeout: 0
838
+ };
839
+ console.log('Fetcher: <' + actualProxyURI + '> Non-HTTP fetch exception: ' + error);
840
+ return this.handleError(dummyResponse, docuri, options); // possible credentials retry
841
+ // return this.failFetch(options, 'fetch failed: ' + error, 999, dummyResponse) // Fake status code: fetch exception
1017
842
 
1018
- this.load(uri, options).then(function (fetchResponse) {
1019
- if (userCallback) {
1020
- if (fetchResponse) {
1021
- if (fetchResponse.ok) {
1022
- userCallback(true, 'OK', fetchResponse);
1023
- } else {
1024
- // console.log('@@@ fetcher.js Should not take this path !!!!!!!!!!!!')
1025
- var oops = 'HTTP error: Status ' + fetchResponse.status + ' (' + fetchResponse.statusText + ')';
1026
-
1027
- if (fetchResponse.responseText) {
1028
- oops += ' ' + fetchResponse.responseText; // not in 404, dns error, nock failure
1029
- }
1030
-
1031
- console.log(oops + ' fetching ' + uri);
1032
- userCallback(false, oops, fetchResponse);
1033
- }
843
+ // handleError expects a response so we fake some important bits.
844
+ /*
845
+ this.handleError(, docuri, options)
846
+ */
847
+ });
848
+ }
849
+
850
+ /**
851
+ * Asks for a doc to be loaded if necessary then calls back
852
+ *
853
+ * Calling methods:
854
+ * nowOrWhenFetched (uri, userCallback)
855
+ * nowOrWhenFetched (uri, options, userCallback)
856
+ * nowOrWhenFetched (uri, referringTerm, userCallback, options) <-- old
857
+ * nowOrWhenFetched (uri, referringTerm, userCallback) <-- old
858
+ *
859
+ * Options include:
860
+ * referringTerm The document in which this link was found.
861
+ * this is valuable when finding the source of bad URIs
862
+ * force boolean. Never mind whether you have tried before,
863
+ * load this from scratch.
864
+ * forceContentType Override the incoming header to force the data to be
865
+ * treated as this content-type.
866
+ *
867
+ * Callback function takes:
868
+ *
869
+ * ok True if the fetch worked, and got a 200 response.
870
+ * False if any error happened
871
+ *
872
+ * errmessage Text error message if not OK.
873
+ *
874
+ * response The fetch Response object (was: XHR) if there was was one
875
+ * includes response.status as the HTTP status if any.
876
+ */
877
+ nowOrWhenFetched(uriIn, p2, userCallback) {
878
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
879
+ const uri = (0, _termValue.termValue)(uriIn);
880
+ if (typeof p2 === 'function') {
881
+ // nowOrWhenFetched (uri, userCallback)
882
+ userCallback = p2;
883
+ } else if (typeof p2 === 'undefined') {// original calling signature
884
+ // referringTerm = undefined
885
+ } else if ((0, _terms.isNamedNode)(p2)) {
886
+ // referringTerm = p2
887
+ options.referringTerm = p2;
888
+ } else {
889
+ // nowOrWhenFetched (uri, options, userCallback)
890
+ options = p2;
891
+ }
892
+ this.load(uri, options).then(fetchResponse => {
893
+ if (userCallback) {
894
+ if (fetchResponse) {
895
+ if (fetchResponse.ok) {
896
+ userCallback(true, 'OK', fetchResponse);
1034
897
  } else {
1035
- var _oops = '@@ nowOrWhenFetched: no response object!';
1036
- console.log(_oops);
1037
- userCallback(false, _oops);
1038
- }
1039
- }
1040
- }, function (err) {
1041
- var message = err.message || err.statusText;
1042
- message = 'Failed to load <' + uri + '> ' + message;
1043
- console.log(message);
898
+ // console.log('@@@ fetcher.js Should not take this path !!!!!!!!!!!!')
899
+ let oops = 'HTTP error: Status ' + fetchResponse.status + ' (' + fetchResponse.statusText + ')';
900
+ if (fetchResponse.responseText) {
901
+ oops += ' ' + fetchResponse.responseText; // not in 404, dns error, nock failure
902
+ }
1044
903
 
1045
- if (err.response && err.response.status) {
1046
- message += ' status: ' + err.response.status;
904
+ console.log(oops + ' fetching ' + uri);
905
+ userCallback(false, oops, fetchResponse);
906
+ }
907
+ } else {
908
+ let oops = '@@ nowOrWhenFetched: no response object!';
909
+ console.log(oops);
910
+ userCallback(false, oops);
1047
911
  }
912
+ }
913
+ }, function (err) {
914
+ var message = err.message || err.statusText;
915
+ message = 'Failed to load <' + uri + '> ' + message;
916
+ console.log(message);
917
+ if (err.response && err.response.status) {
918
+ message += ' status: ' + err.response.status;
919
+ }
920
+ userCallback(false, message, err.response);
921
+ });
922
+ }
1048
923
 
1049
- userCallback(false, message, err.response);
1050
- });
924
+ /**
925
+ * Records a status message (as a literal node) by appending it to the
926
+ * request's metadata status collection.
927
+ *
928
+ */
929
+ addStatus(req, statusMessage) {
930
+ // <Debug about="parsePerformance">
931
+ let now = new Date();
932
+ statusMessage = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '.' + now.getMilliseconds() + '] ' + statusMessage;
933
+ // </Debug>
934
+ let kb = this.store;
935
+ const statusNode = kb.the(req, this.ns.link('status'));
936
+ if ((0, _terms.isCollection)(statusNode)) {
937
+ statusNode.append(kb.rdfFactory.literal(statusMessage));
938
+ } else {
939
+ _log.default.warn('web.js: No list to add to: ' + statusNode + ',' + statusMessage);
1051
940
  }
1052
- /**
1053
- * Records a status message (as a literal node) by appending it to the
1054
- * request's metadata status collection.
1055
- *
1056
- */
1057
-
1058
- }, {
1059
- key: "addStatus",
1060
- value: function addStatus(req, statusMessage) {
1061
- // <Debug about="parsePerformance">
1062
- var now = new Date();
1063
- statusMessage = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '.' + now.getMilliseconds() + '] ' + statusMessage; // </Debug>
1064
-
1065
- var kb = this.store;
1066
- var statusNode = kb.the(req, this.ns.link('status'));
941
+ }
1067
942
 
1068
- if ((0, _terms.isCollection)(statusNode)) {
1069
- statusNode.append(kb.rdfFactory.literal(statusMessage));
943
+ /**
944
+ * Records errors in the system on failure:
945
+ *
946
+ * - Adds an entry to the request status collection
947
+ * - Adds an error triple with the fail message to the metadata
948
+ * - Fires the 'fail' callback
949
+ * - Rejects with an error result object, which has a response object if any
950
+ */
951
+ failFetch(options, errorMessage, statusCode, response) {
952
+ this.addStatus(options.req, errorMessage);
953
+ if (!options.noMeta) {
954
+ this.store.add(options.original, this.ns.link('error'), this.store.rdfFactory.literal(errorMessage));
955
+ }
956
+ let meth = (options.method || 'GET').toUpperCase();
957
+ let isGet = meth === 'GET' || meth === 'HEAD';
958
+ if (isGet) {
959
+ // only cache the status code on GET or HEAD
960
+ if (!options.resource.equals(options.original)) {
961
+ // console.log('@@ Recording failure ' + meth + ' original ' + options.original +option '( as ' + options.resource + ') : ' + statusCode)
1070
962
  } else {
1071
- _log.default.warn('web.js: No list to add to: ' + statusNode + ',' + statusMessage);
963
+ // console.log('@@ Recording ' + meth + ' failure for ' + options.original + ': ' + statusCode)
1072
964
  }
965
+ this.requested[Uri.docpart(options.original.value)] = statusCode;
966
+ this.fireCallbacks('fail', [options.original.value, errorMessage]);
1073
967
  }
1074
- /**
1075
- * Records errors in the system on failure:
1076
- *
1077
- * - Adds an entry to the request status collection
1078
- * - Adds an error triple with the fail message to the metadata
1079
- * - Fires the 'fail' callback
1080
- * - Rejects with an error result object, which has a response object if any
1081
- */
1082
-
1083
- }, {
1084
- key: "failFetch",
1085
- value: function failFetch(options, errorMessage, statusCode, response) {
1086
- this.addStatus(options.req, errorMessage);
1087
-
1088
- if (!options.noMeta) {
1089
- this.store.add(options.original, this.ns.link('error'), this.store.rdfFactory.literal(errorMessage));
1090
- }
1091
-
1092
- var meth = (options.method || 'GET').toUpperCase();
1093
- var isGet = meth === 'GET' || meth === 'HEAD';
968
+ var err = new Error('Fetcher: ' + errorMessage);
1094
969
 
1095
- if (isGet) {
1096
- // only cache the status code on GET or HEAD
1097
- if (!options.resource.equals(options.original)) {// console.log('@@ Recording failure ' + meth + ' original ' + options.original +option '( as ' + options.resource + ') : ' + statusCode)
1098
- } else {// console.log('@@ Recording ' + meth + ' failure for ' + options.original + ': ' + statusCode)
1099
- }
1100
-
1101
- this.requested[Uri.docpart(options.original.value)] = statusCode;
1102
- this.fireCallbacks('fail', [options.original.value, errorMessage]);
1103
- }
1104
-
1105
- var err = new Error('Fetcher: ' + errorMessage); // err.ok = false // Is taken as a response, will work too @@ phase out?
1106
-
1107
- err.status = statusCode;
1108
- err.statusText = errorMessage;
1109
- err.response = response;
1110
- return Promise.reject(err);
1111
- } // in the why part of the quad distinguish between HTML and HTTP header
1112
- // Reverse is set iif the link was rev= as opposed to rel=
1113
-
1114
- }, {
1115
- key: "linkData",
1116
- value: function linkData(originalUri, rel, uri, why, reverse) {
1117
- if (!uri) return;
1118
- var kb = this.store;
1119
- var predicate; // See http://www.w3.org/TR/powder-dr/#httplink for describedby 2008-12-10
1120
-
1121
- var obj = kb.rdfFactory.namedNode(Uri.join(uri, originalUri.value));
1122
-
1123
- if (rel === 'alternate' || rel === 'seeAlso' || rel === 'meta' || rel === 'describedby') {
1124
- if (obj.value === originalUri.value) {
1125
- return;
1126
- }
1127
-
1128
- predicate = this.ns.rdfs('seeAlso');
1129
- } else if (rel === 'type') {
1130
- predicate = kb.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
1131
- } else {
1132
- // See https://www.iana.org/assignments/link-relations/link-relations.xml
1133
- // Alas not yet in RDF yet for each predicate
1134
- // encode space in e.g. rel="shortcut icon"
1135
- predicate = kb.rdfFactory.namedNode(Uri.join(encodeURIComponent(rel), 'http://www.iana.org/assignments/link-relations/'));
1136
- }
970
+ // err.ok = false // Is taken as a response, will work too @@ phase out?
971
+ err.status = statusCode;
972
+ err.statusText = errorMessage;
973
+ err.response = response;
974
+ return Promise.reject(err);
975
+ }
1137
976
 
1138
- if (reverse) {
1139
- kb.add(obj, predicate, originalUri, why);
1140
- } else {
1141
- kb.add(originalUri, predicate, obj, why);
977
+ // in the why part of the quad distinguish between HTML and HTTP header
978
+ // Reverse is set iif the link was rev= as opposed to rel=
979
+ linkData(originalUri, rel, uri, why, reverse) {
980
+ if (!uri) return;
981
+ let kb = this.store;
982
+ let predicate;
983
+ // See http://www.w3.org/TR/powder-dr/#httplink for describedby 2008-12-10
984
+ let obj = kb.rdfFactory.namedNode(Uri.join(uri, originalUri.value));
985
+ if (rel === 'alternate' || rel === 'seeAlso' || rel === 'meta' || rel === 'describedby') {
986
+ if (obj.value === originalUri.value) {
987
+ return;
1142
988
  }
989
+ predicate = this.ns.rdfs('seeAlso');
990
+ } else if (rel === 'type') {
991
+ predicate = kb.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
992
+ } else {
993
+ // See https://www.iana.org/assignments/link-relations/link-relations.xml
994
+ // Alas not yet in RDF yet for each predicate
995
+ // encode space in e.g. rel="shortcut icon"
996
+ predicate = kb.rdfFactory.namedNode(Uri.join(encodeURIComponent(rel), 'http://www.iana.org/assignments/link-relations/'));
997
+ }
998
+ if (reverse) {
999
+ kb.add(obj, predicate, originalUri, why);
1000
+ } else {
1001
+ kb.add(originalUri, predicate, obj, why);
1143
1002
  }
1144
- }, {
1145
- key: "parseLinkHeader",
1146
- value: function parseLinkHeader(linkHeader, originalUri, reqNode) {
1147
- if (!linkHeader) {
1148
- return;
1149
- } // const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} \t]+=(([^()<>@,;:"/[]?={} \t]+)|("[^"]*")))*(,|$)/g
1150
- // const paramexp = /[^()<>@,;:"/[]?={} \t]+=(([^()<>@,;:"/[]?={} \t]+)|("[^"]*"))/g
1151
- // From https://www.dcode.fr/regular-expression-simplificator:
1152
- // const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} t]+=["]))*[,$]/g
1153
- // const paramexp = /[^\\<>@,;:"\/\[\]?={} \t]+=["])/g
1154
- // Original:
1155
-
1156
-
1157
- var linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*")))*(,|$)/g;
1158
- var paramexp = /[^\(\)<>@,;:"\/\[\]\?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*"))/g;
1159
- var matches = linkHeader.match(linkexp);
1160
- if (matches == null) return;
1161
-
1162
- for (var i = 0; i < matches.length; i++) {
1163
- var split = matches[i].split('>');
1164
- var href = split[0].substring(1);
1165
- var ps = split[1];
1166
- var s = ps.match(paramexp);
1167
- if (s == null) return;
1168
-
1169
- for (var j = 0; j < s.length; j++) {
1170
- var p = s[j];
1171
- var paramsplit = p.split('='); // var name = paramsplit[0]
1172
-
1173
- var rel = paramsplit[1].replace(/["']/g, ''); // '"
1174
-
1175
- this.linkData(originalUri, rel, href, reqNode);
1176
- }
1003
+ }
1004
+ parseLinkHeader(linkHeader, originalUri, reqNode) {
1005
+ if (!linkHeader) {
1006
+ return;
1007
+ }
1008
+
1009
+ // const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} \t]+=(([^()<>@,;:"/[]?={} \t]+)|("[^"]*")))*(,|$)/g
1010
+ // const paramexp = /[^()<>@,;:"/[]?={} \t]+=(([^()<>@,;:"/[]?={} \t]+)|("[^"]*"))/g
1011
+
1012
+ // From https://www.dcode.fr/regular-expression-simplificator:
1013
+ // const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} t]+=["]))*[,$]/g
1014
+ // const paramexp = /[^\\<>@,;:"\/\[\]?={} \t]+=["])/g
1015
+ // Original:
1016
+ const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*")))*(,|$)/g;
1017
+ const paramexp = /[^\(\)<>@,;:"\/\[\]\?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*"))/g;
1018
+ const matches = linkHeader.match(linkexp);
1019
+ if (matches == null) return;
1020
+ for (let i = 0; i < matches.length; i++) {
1021
+ let split = matches[i].split('>');
1022
+ let href = split[0].substring(1);
1023
+ let ps = split[1];
1024
+ let s = ps.match(paramexp);
1025
+ if (s == null) return;
1026
+ for (let j = 0; j < s.length; j++) {
1027
+ let p = s[j];
1028
+ let paramsplit = p.split('=');
1029
+ // var name = paramsplit[0]
1030
+ let rel = paramsplit[1].replace(/["']/g, ''); // '"
1031
+ this.linkData(originalUri, rel, href, reqNode);
1177
1032
  }
1178
1033
  }
1179
- }, {
1180
- key: "doneFetch",
1181
- value: function doneFetch(options, response) {
1182
- this.addStatus(options.req, 'Done.');
1183
- this.requested[options.original.value] = 'done';
1184
- this.fireCallbacks('done', [options.original.value]);
1185
- response.req = options.req; // Set the request meta blank node
1034
+ }
1035
+ doneFetch(options, response) {
1036
+ this.addStatus(options.req, 'Done.');
1037
+ this.requested[options.original.value] = 'done';
1038
+ this.fireCallbacks('done', [options.original.value]);
1039
+ response.req = options.req; // Set the request meta blank node
1186
1040
 
1187
- return response;
1188
- }
1189
- /**
1190
- * Note two nodes are now smushed
1191
- * If only one was flagged as looked up, then the new node is looked up again,
1192
- * which will make sure all the URIs are dereferenced
1193
- */
1041
+ return response;
1042
+ }
1194
1043
 
1195
- }, {
1196
- key: "nowKnownAs",
1197
- value: function nowKnownAs(was, now) {
1198
- if (this.lookedUp[was.value]) {
1199
- // Transfer userCallback
1200
- if (!this.lookedUp[now.value]) {
1201
- this.lookUpThing(now, was);
1202
- }
1203
- } else if (this.lookedUp[now.value]) {
1204
- if (!this.lookedUp[was.value]) {
1205
- this.lookUpThing(was, now);
1206
- }
1044
+ /**
1045
+ * Note two nodes are now smushed
1046
+ * If only one was flagged as looked up, then the new node is looked up again,
1047
+ * which will make sure all the URIs are dereferenced
1048
+ */
1049
+ nowKnownAs(was, now) {
1050
+ if (this.lookedUp[was.value]) {
1051
+ // Transfer userCallback
1052
+ if (!this.lookedUp[now.value]) {
1053
+ this.lookUpThing(now, was);
1207
1054
  }
1208
- }
1209
- /**
1210
- * Writes back to the web what we have in the store for this uri
1211
- */
1212
-
1213
- }, {
1214
- key: "putBack",
1215
- value: function putBack(uri) {
1216
- var _this6 = this;
1217
-
1218
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1219
- var uriSting = (0, _termValue.termValue)(uri);
1220
- var doc = new _namedNode.default(uriSting).doc(); // strip off #
1221
-
1222
- options.contentType = options["content-type"] || options["Content-Type"] || options.contentType || _types.TurtleContentType;
1223
-
1224
- if (options.contentType === 'application/ld+json') {
1225
- return new Promise(function (resolve, reject) {
1226
- (0, _serialize.default)(doc, _this6.store, doc.uri, options.contentType, function (err, jsonString) {
1227
- if (err) {
1228
- reject(err);
1229
- } else {
1230
- // @ts-ignore
1231
- options.data = jsonString;
1232
-
1233
- _this6.webOperation('PUT', uri, options).then(function (res) {
1234
- return resolve(res);
1235
- }).catch(function (error) {
1236
- return reject(error);
1237
- });
1238
- }
1239
- });
1240
- });
1055
+ } else if (this.lookedUp[now.value]) {
1056
+ if (!this.lookedUp[was.value]) {
1057
+ this.lookUpThing(was, now);
1241
1058
  }
1242
-
1243
- options.data = (0, _serialize.default)(doc, this.store, doc.value, options.contentType);
1244
- return this.webOperation('PUT', uriSting, options);
1245
1059
  }
1246
- }, {
1247
- key: "webCopy",
1248
- value: function webCopy(here, there, contentType) {
1249
- var _this7 = this;
1060
+ }
1250
1061
 
1251
- return this.webOperation('GET', here).then(function (result) {
1252
- return _this7.webOperation('PUT', // change to binary from text
1253
- there, {
1254
- data: result.responseText,
1255
- contentType: contentType
1062
+ /**
1063
+ * Writes back to the web what we have in the store for this uri
1064
+ */
1065
+ putBack(uri) {
1066
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1067
+ const uriSting = (0, _termValue.termValue)(uri);
1068
+ let doc = new _namedNode.default(uriSting).doc(); // strip off #
1069
+ options.contentType = options["content-type"] || options["Content-Type"] || options.contentType || _types.TurtleContentType;
1070
+ if (options.contentType === 'application/ld+json') {
1071
+ return new Promise((resolve, reject) => {
1072
+ (0, _serialize.default)(doc, this.store, doc.uri, options.contentType, (err, jsonString) => {
1073
+ if (err) {
1074
+ reject(err);
1075
+ } else {
1076
+ // @ts-ignore
1077
+ options.data = jsonString;
1078
+ this.webOperation('PUT', uri, options).then(res => resolve(res)).catch(error => reject(error));
1079
+ }
1256
1080
  });
1257
1081
  });
1258
1082
  }
1259
- }, {
1260
- key: "delete",
1261
- value: function _delete(uri, options) {
1262
- var _this8 = this;
1263
-
1264
- return this.webOperation('DELETE', uri, options).then(function (response) {
1265
- _this8.requested[uri] = 404;
1266
- _this8.nonexistent[uri] = true;
1267
-
1268
- _this8.unload(_this8.store.rdfFactory.namedNode(uri));
1269
-
1270
- return response;
1083
+ options.data = (0, _serialize.default)(doc, this.store, doc.value, options.contentType);
1084
+ return this.webOperation('PUT', uriSting, options);
1085
+ }
1086
+ webCopy(here, there, contentType) {
1087
+ return this.webOperation('GET', here).then(result => {
1088
+ return this.webOperation('PUT',
1089
+ // change to binary from text
1090
+ there, {
1091
+ data: result.responseText,
1092
+ contentType
1271
1093
  });
1272
- }
1273
- /** Create an empty resource if it really does not exist
1274
- * Be absolutely sure something does not exist before creating a new empty file
1275
- * as otherwise existing could be deleted.
1276
- * @param doc - The resource
1277
- */
1278
-
1279
- }, {
1280
- key: "createIfNotExists",
1281
- value: function () {
1282
- var _createIfNotExists = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(doc) {
1283
- var contentType,
1284
- data,
1285
- fetcher,
1286
- response,
1287
- _args = arguments;
1288
- return _regenerator.default.wrap(function _callee$(_context) {
1289
- while (1) {
1290
- switch (_context.prev = _context.next) {
1291
- case 0:
1292
- contentType = _args.length > 1 && _args[1] !== undefined ? _args[1] : _types.TurtleContentType;
1293
- data = _args.length > 2 && _args[2] !== undefined ? _args[2] : '';
1294
- fetcher = this;
1295
- _context.prev = 3;
1296
- _context.next = 6;
1297
- return fetcher.load(doc);
1298
-
1299
- case 6:
1300
- response = _context.sent;
1301
- _context.next = 29;
1302
- break;
1303
-
1304
- case 9:
1305
- _context.prev = 9;
1306
- _context.t0 = _context["catch"](3);
1307
-
1308
- if (!(_context.t0.response.status === 404)) {
1309
- _context.next = 27;
1310
- break;
1311
- }
1312
-
1313
- console.log('createIfNotExists: doc does NOT exist, will create... ' + doc);
1314
- _context.prev = 13;
1315
- _context.next = 16;
1316
- return fetcher.webOperation('PUT', doc.value, {
1317
- data: data,
1318
- contentType: contentType
1319
- });
1320
-
1321
- case 16:
1322
- response = _context.sent;
1323
- _context.next = 23;
1324
- break;
1325
-
1326
- case 19:
1327
- _context.prev = 19;
1328
- _context.t1 = _context["catch"](13);
1329
- console.log('createIfNotExists doc FAILED: ' + doc + ': ' + _context.t1);
1330
- throw _context.t1;
1331
-
1332
- case 23:
1333
- delete fetcher.requested[doc.value]; // delete cached 404 error
1334
- // console.log('createIfNotExists doc created ok ' + doc)
1335
-
1336
- return _context.abrupt("return", response);
1337
-
1338
- case 27:
1339
- console.log('createIfNotExists doc load error NOT 404: ' + doc + ': ' + _context.t0);
1340
- throw _context.t0;
1341
-
1342
- case 29:
1343
- return _context.abrupt("return", response);
1344
-
1345
- case 30:
1346
- case "end":
1347
- return _context.stop();
1348
- }
1349
- }
1350
- }, _callee, this, [[3, 9], [13, 19]]);
1351
- }));
1352
-
1353
- function createIfNotExists(_x) {
1354
- return _createIfNotExists.apply(this, arguments);
1355
- }
1356
-
1357
- return createIfNotExists;
1358
- }()
1359
- /**
1360
- * @param parentURI URI of parent container
1361
- * @param folderName - Optional folder name (slug)
1362
- * @param data - Optional folder metadata
1363
- */
1364
-
1365
- }, {
1366
- key: "createContainer",
1367
- value: function createContainer(parentURI, folderName, data) {
1368
- var headers = {
1369
- // Force the right mime type for containers
1370
- 'content-type': _types.TurtleContentType,
1371
- 'link': this.ns.ldp('BasicContainer') + '; rel="type"'
1372
- };
1373
-
1374
- if (folderName) {
1375
- headers['slug'] = folderName;
1376
- } // @ts-ignore These headers lack some of the required operators.
1377
-
1378
-
1379
- var options = {
1380
- headers: headers
1381
- };
1382
-
1383
- if (data) {
1384
- options.body = data;
1385
- }
1386
-
1387
- return this.webOperation('POST', parentURI, options);
1388
- }
1389
- }, {
1390
- key: "invalidateCache",
1391
- value: function invalidateCache(iri) {
1392
- var uri = (0, _termValue.termValue)(iri);
1393
- var fetcher = this; // @ts-ignore
1394
-
1395
- if (fetcher.fetchQueue && fetcher.fetchQueue[uri]) {
1396
- console.log('Internal error - fetchQueue exists ' + uri);
1397
- var promise = fetcher.fetchQueue[uri];
1094
+ });
1095
+ }
1096
+ delete(uri, options) {
1097
+ return this.webOperation('DELETE', uri, options).then(response => {
1098
+ this.requested[uri] = 404;
1099
+ this.nonexistent[uri] = true;
1100
+ this.unload(this.store.rdfFactory.namedNode(uri));
1101
+ return response;
1102
+ });
1103
+ }
1398
1104
 
1399
- if (promise['PromiseStatus'] === 'resolved') {
1400
- delete fetcher.fetchQueue[uri];
1401
- } else {
1402
- // pending
1403
- delete fetcher.fetchQueue[uri];
1404
- console.log('*** Fetcher: pending fetchQueue deleted ' + uri);
1105
+ /** Create an empty resource if it really does not exist
1106
+ * Be absolutely sure something does not exist before creating a new empty file
1107
+ * as otherwise existing could be deleted.
1108
+ * @param doc - The resource
1109
+ */
1110
+ async createIfNotExists(doc) {
1111
+ let contentType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _types.TurtleContentType;
1112
+ let data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
1113
+ const fetcher = this;
1114
+ try {
1115
+ var response = await fetcher.load(doc);
1116
+ } catch (err) {
1117
+ // @ts-ignore
1118
+ if (err.response.status === 404) {
1119
+ console.log('createIfNotExists: doc does NOT exist, will create... ' + doc);
1120
+ try {
1121
+ response = await fetcher.webOperation('PUT', doc.value, {
1122
+ data,
1123
+ contentType
1124
+ });
1125
+ } catch (err) {
1126
+ console.log('createIfNotExists doc FAILED: ' + doc + ': ' + err);
1127
+ throw err;
1405
1128
  }
1406
- }
1407
-
1408
- if (fetcher.requested[uri] && fetcher.requested[uri] !== 'done' && fetcher.requested[uri] !== 'failed' && fetcher.requested[uri] !== 404) {
1409
- var msg = "Rdflib: fetcher: Destructive operation on <".concat(fetcher.requested[uri], "> file being fetched! ") + uri;
1410
- console.error(msg); // alert(msg)
1129
+ delete fetcher.requested[doc.value]; // delete cached 404 error
1130
+ // console.log('createIfNotExists doc created ok ' + doc)
1131
+ return response;
1411
1132
  } else {
1412
- delete fetcher.requested[uri]; // invalidate read cache -- @@ messes up logic if request in progress ??
1413
-
1414
- delete fetcher.nonexistent[uri];
1133
+ console.log('createIfNotExists doc load error NOT 404: ' + doc + ': ' + err);
1134
+ throw err;
1415
1135
  }
1416
1136
  }
1417
- /**
1418
- * A generic web operation, at the fetch() level.
1419
- * does not involve the quad store.
1420
- *
1421
- * Returns promise of Response
1422
- * If data is returned, copies it to response.responseText before returning
1423
- */
1424
-
1425
- }, {
1426
- key: "webOperation",
1427
- value: function webOperation(method, uriIn) {
1428
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1429
- var uri = (0, _termValue.termValue)(uriIn);
1430
- options.method = method;
1431
- options.body = options.data || options.body;
1432
- options.force = true;
1433
- var fetcher = this;
1434
-
1435
- if (options.body && !options.contentType) {
1436
- throw new Error('Web operation sending data must have a defined contentType.');
1437
- }
1137
+ // console.log('createIfNotExists: doc exists, all good: ' + doc)
1138
+ return response;
1139
+ }
1438
1140
 
1439
- if (options.contentType) {
1440
- options.headers = options.headers || {};
1441
- options.headers['content-type'] = options.contentType;
1141
+ /**
1142
+ * @param parentURI URI of parent container
1143
+ * @param folderName - Optional folder name (slug)
1144
+ * @param data - Optional folder metadata
1145
+ */
1146
+ createContainer(parentURI, folderName, data) {
1147
+ let headers = {
1148
+ // Force the right mime type for containers
1149
+ 'content-type': _types.TurtleContentType,
1150
+ 'link': this.ns.ldp('BasicContainer') + '; rel="type"'
1151
+ };
1152
+ if (folderName) {
1153
+ headers['slug'] = folderName;
1154
+ }
1155
+
1156
+ // @ts-ignore These headers lack some of the required operators.
1157
+ let options = {
1158
+ headers
1159
+ };
1160
+ if (data) {
1161
+ options.body = data;
1162
+ }
1163
+ return this.webOperation('POST', parentURI, options);
1164
+ }
1165
+ invalidateCache(iri) {
1166
+ const uri = (0, _termValue.termValue)(iri);
1167
+ const fetcher = this;
1168
+ // @ts-ignore
1169
+ if (fetcher.fetchQueue && fetcher.fetchQueue[uri]) {
1170
+ console.log('Internal error - fetchQueue exists ' + uri);
1171
+ var promise = fetcher.fetchQueue[uri];
1172
+ if (promise['PromiseStatus'] === 'resolved') {
1173
+ delete fetcher.fetchQueue[uri];
1174
+ } else {
1175
+ // pending
1176
+ delete fetcher.fetchQueue[uri];
1177
+ console.log('*** Fetcher: pending fetchQueue deleted ' + uri);
1442
1178
  }
1179
+ }
1180
+ if (fetcher.requested[uri] && fetcher.requested[uri] !== 'done' && fetcher.requested[uri] !== 'failed' && fetcher.requested[uri] !== 404) {
1181
+ let msg = `Rdflib: fetcher: Destructive operation on <${fetcher.requested[uri]}> file being fetched! ` + uri;
1182
+ console.error(msg);
1183
+ // alert(msg)
1184
+ } else {
1185
+ delete fetcher.requested[uri]; // invalidate read cache -- @@ messes up logic if request in progress ??
1186
+ delete fetcher.nonexistent[uri];
1187
+ }
1188
+ }
1443
1189
 
1444
- Fetcher.setCredentials(uri, options);
1445
- return new Promise(function (resolve, reject) {
1446
- fetcher._fetch(uri, options).then(function (response) {
1447
- if (response.ok) {
1448
- if (method === 'PUT' || method === 'PATCH' || method === 'POST' || method === 'DELETE') {
1449
- fetcher.invalidateCache(uri);
1450
- } // response.body with Chrome can't be relied on
1451
-
1452
-
1453
- if (response.text) {
1454
- // Was: response.body https://github.com/linkeddata/rdflib.js/issues/506
1455
- response.text().then(function (data) {
1456
- response.responseText = data;
1457
- resolve(response);
1458
- });
1459
- } else {
1190
+ /**
1191
+ * A generic web operation, at the fetch() level.
1192
+ * does not involve the quad store.
1193
+ *
1194
+ * Returns promise of Response
1195
+ * If data is returned, copies it to response.responseText before returning
1196
+ */
1197
+ webOperation(method, uriIn) {
1198
+ let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1199
+ const uri = (0, _termValue.termValue)(uriIn);
1200
+ options.method = method;
1201
+ options.body = options.data || options.body;
1202
+ options.force = true;
1203
+ const fetcher = this;
1204
+ if (options.body && !options.contentType) {
1205
+ throw new Error('Web operation sending data must have a defined contentType.');
1206
+ }
1207
+ if (options.contentType) {
1208
+ options.headers = options.headers || {};
1209
+ options.headers['content-type'] = options.contentType;
1210
+ }
1211
+ Fetcher.setCredentials(uri, options);
1212
+ return new Promise(function (resolve, reject) {
1213
+ fetcher._fetch(uri, options).then(response => {
1214
+ if (response.ok) {
1215
+ if (method === 'PUT' || method === 'PATCH' || method === 'POST' || method === 'DELETE') {
1216
+ fetcher.invalidateCache(uri);
1217
+ } // response.body with Chrome can't be relied on
1218
+ if (response.text) {
1219
+ // Was: response.body https://github.com/linkeddata/rdflib.js/issues/506
1220
+ response.text().then(data => {
1221
+ response.responseText = data;
1460
1222
  resolve(response);
1461
- }
1223
+ });
1462
1224
  } else {
1463
- var msg = 'Web error: ' + response.status;
1464
- if (response.statusText) msg += ' (' + response.statusText + ')';
1465
- msg += ' on ' + method + ' of <' + uri + '>';
1466
- if (response.responseText) msg += ': ' + response.responseText;
1467
- var e2 = new Error(msg);
1468
- e2.response = response;
1469
- reject(e2);
1225
+ resolve(response);
1470
1226
  }
1471
- }, function (err) {
1472
- var msg = 'Fetch error for ' + method + ' of <' + uri + '>:' + err;
1473
- reject(new Error(msg));
1474
- });
1475
- });
1476
- }
1477
- /**
1478
- * Looks up something.
1479
- * Looks up all the URIs a things has.
1480
- *
1481
- * @param term - canonical term for the thing whose URI is
1482
- * to be dereferenced
1483
- * @param rterm - the resource which referred to this
1484
- * (for tracking bad links)
1485
- */
1486
-
1487
- }, {
1488
- key: "lookUpThing",
1489
- value: function lookUpThing(term, rterm) {
1490
- var _this9 = this;
1491
-
1492
- var uris = this.store.uris(term); // Get all URIs
1493
-
1494
- uris = uris.map(function (u) {
1495
- return Uri.docpart(u);
1496
- }); // Drop hash fragments
1497
-
1498
- uris.forEach(function (u) {
1499
- _this9.lookedUp[u] = true;
1500
- }); // @ts-ignore Recursive type
1501
-
1502
- return this.load(uris, {
1503
- referringTerm: rterm
1227
+ } else {
1228
+ let msg = 'Web error: ' + response.status;
1229
+ if (response.statusText) msg += ' (' + response.statusText + ')';
1230
+ msg += ' on ' + method + ' of <' + uri + '>';
1231
+ if (response.responseText) msg += ': ' + response.responseText;
1232
+ let e2 = new Error(msg);
1233
+ e2.response = response;
1234
+ reject(e2);
1235
+ }
1236
+ }, err => {
1237
+ let msg = 'Fetch error for ' + method + ' of <' + uri + '>:' + err;
1238
+ reject(new Error(msg));
1504
1239
  });
1505
- }
1506
- /**
1507
- * Looks up response header.
1508
- *
1509
- * @returns {Array|undefined} a list of header values found in a stored HTTP
1510
- * response, or [] if response was found but no header found,
1511
- * or undefined if no response is available.
1512
- * Looks for { [] link:requestedURI ?uri; link:response [ httph:header-name ?value ] }
1513
- */
1514
-
1515
- }, {
1516
- key: "getHeader",
1517
- value: function getHeader(doc, header) {
1518
- var kb = this.store; // look for the URI (AS A STRING NOT A NODE) for a stored request
1519
-
1520
- var docuri = doc.value;
1521
- var requests = kb.each(undefined, this.ns.link('requestedURI'), kb.rdfFactory.literal(docuri));
1522
-
1523
- for (var r = 0; r < requests.length; r++) {
1524
- var request = requests[r];
1240
+ });
1241
+ }
1525
1242
 
1526
- if (request !== undefined) {
1527
- var _response = kb.any(request, this.ns.link('response'));
1243
+ /**
1244
+ * Looks up something.
1245
+ * Looks up all the URIs a things has.
1246
+ *
1247
+ * @param term - canonical term for the thing whose URI is
1248
+ * to be dereferenced
1249
+ * @param rterm - the resource which referred to this
1250
+ * (for tracking bad links)
1251
+ */
1252
+ lookUpThing(term, rterm) {
1253
+ let uris = this.store.uris(term); // Get all URIs
1254
+ uris = uris.map(u => Uri.docpart(u)); // Drop hash fragments
1528
1255
 
1529
- if (_response !== undefined && kb.anyValue(_response, this.ns.http('status')) && kb.anyValue(_response, this.ns.http('status')).startsWith('2')) {
1530
- // Only look at success returns - not 401 error messagess etc
1531
- var results = kb.each(_response, this.ns.httph(header.toLowerCase()));
1256
+ uris.forEach(u => {
1257
+ this.lookedUp[u] = true;
1258
+ });
1532
1259
 
1533
- if (results.length) {
1534
- return results.map(function (v) {
1535
- return v.value;
1536
- });
1537
- }
1260
+ // @ts-ignore Recursive type
1261
+ return this.load(uris, {
1262
+ referringTerm: rterm
1263
+ });
1264
+ }
1538
1265
 
1539
- return [];
1266
+ /**
1267
+ * Looks up response header.
1268
+ *
1269
+ * @returns {Array|undefined} a list of header values found in a stored HTTP
1270
+ * response, or [] if response was found but no header found,
1271
+ * or undefined if no response is available.
1272
+ * Looks for { [] link:requestedURI ?uri; link:response [ httph:header-name ?value ] }
1273
+ */
1274
+ getHeader(doc, header) {
1275
+ const kb = this.store; // look for the URI (AS A STRING NOT A NODE) for a stored request
1276
+ const docuri = doc.value;
1277
+ const requests = kb.each(undefined, this.ns.link('requestedURI'), kb.rdfFactory.literal(docuri));
1278
+ for (let r = 0; r < requests.length; r++) {
1279
+ let request = requests[r];
1280
+ if (request !== undefined) {
1281
+ let response = kb.any(request, this.ns.link('response'));
1282
+ if (response !== undefined && kb.anyValue(response, this.ns.http('status')) && kb.anyValue(response, this.ns.http('status')).startsWith('2')) {
1283
+ // Only look at success returns - not 401 error messagess etc
1284
+ let results = kb.each(response, this.ns.httph(header.toLowerCase()));
1285
+ if (results.length) {
1286
+ return results.map(v => {
1287
+ return v.value;
1288
+ });
1540
1289
  }
1290
+ return [];
1541
1291
  }
1542
1292
  }
1543
-
1544
- return undefined;
1545
1293
  }
1546
- }, {
1547
- key: "saveRequestMetadata",
1548
- value: function saveRequestMetadata(docuri, options) {
1549
- var req = options.req;
1550
- var kb = this.store;
1551
- var rterm = options.referringTerm;
1552
- this.addStatus(options.req, 'Accept: ' + options.headers['accept']);
1553
-
1554
- if ((0, _terms.isNamedNode)(rterm)) {
1555
- kb.add(kb.rdfFactory.namedNode(docuri), this.ns.link('requestedBy'), rterm, this.appNode);
1294
+ return undefined;
1295
+ }
1296
+ saveRequestMetadata(docuri, options) {
1297
+ let req = options.req;
1298
+ let kb = this.store;
1299
+ let rterm = options.referringTerm;
1300
+ this.addStatus(options.req, 'Accept: ' + options.headers['accept']);
1301
+ if ((0, _terms.isNamedNode)(rterm)) {
1302
+ kb.add(kb.rdfFactory.namedNode(docuri), this.ns.link('requestedBy'), rterm, this.appNode);
1303
+ }
1304
+ if (options.original && options.original.value !== docuri) {
1305
+ kb.add(req, this.ns.link('orginalURI'), kb.rdfFactory.literal(options.original.value), this.appNode);
1306
+ }
1307
+ const now = new Date();
1308
+ const timeNow = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '] ';
1309
+ kb.add(req, this.ns.rdfs('label'), kb.rdfFactory.literal(timeNow + ' Request for ' + docuri), this.appNode);
1310
+ // We store the docuri as a string, not as a node,
1311
+ // see https://github.com/linkeddata/rdflib.js/pull/427#pullrequestreview-447910061
1312
+ kb.add(req, this.ns.link('requestedURI'), kb.rdfFactory.literal(docuri), this.appNode);
1313
+ kb.add(req, this.ns.link('status'), kb.collection(), this.appNode);
1314
+ }
1315
+ saveResponseMetadata(response, options) {
1316
+ const kb = this.store;
1317
+ let responseNode = kb.bnode();
1318
+ kb.add(options.req, this.ns.link('response'), responseNode, responseNode);
1319
+ kb.add(responseNode, this.ns.http('status'), kb.rdfFactory.literal(response.status), responseNode);
1320
+ kb.add(responseNode, this.ns.http('statusText'), kb.rdfFactory.literal(response.statusText), responseNode);
1321
+
1322
+ // Save the response headers
1323
+ response.headers.forEach((value, header) => {
1324
+ kb.add(responseNode, this.ns.httph(header), this.store.rdfFactory.literal(value), responseNode);
1325
+ if (header === 'content-type') {
1326
+ kb.add(options.resource, this.ns.rdf('type'), kb.rdfFactory.namedNode(Util.mediaTypeClass(value).value), responseNode);
1556
1327
  }
1557
-
1558
- if (options.original && options.original.value !== docuri) {
1559
- kb.add(req, this.ns.link('orginalURI'), kb.rdfFactory.literal(options.original.value), this.appNode);
1328
+ });
1329
+ return responseNode;
1330
+ }
1331
+ objectRefresh(term) {
1332
+ let uris = this.store.uris(term); // Get all URIs
1333
+ if (typeof uris !== 'undefined') {
1334
+ for (let i = 0; i < uris.length; i++) {
1335
+ this.refresh(this.store.rdfFactory.namedNode(Uri.docpart(uris[i])));
1336
+ // what about rterm?
1560
1337
  }
1561
-
1562
- var now = new Date();
1563
- var timeNow = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '] ';
1564
- kb.add(req, this.ns.rdfs('label'), kb.rdfFactory.literal(timeNow + ' Request for ' + docuri), this.appNode); // We store the docuri as a string, not as a node,
1565
- // see https://github.com/linkeddata/rdflib.js/pull/427#pullrequestreview-447910061
1566
-
1567
- kb.add(req, this.ns.link('requestedURI'), kb.rdfFactory.literal(docuri), this.appNode);
1568
- kb.add(req, this.ns.link('status'), kb.collection(), this.appNode);
1569
1338
  }
1570
- }, {
1571
- key: "saveResponseMetadata",
1572
- value: function saveResponseMetadata(response, options) {
1573
- var _this10 = this;
1574
-
1575
- var kb = this.store;
1576
- var responseNode = kb.bnode();
1577
- kb.add(options.req, this.ns.link('response'), responseNode, responseNode);
1578
- kb.add(responseNode, this.ns.http('status'), kb.rdfFactory.literal(response.status), responseNode);
1579
- kb.add(responseNode, this.ns.http('statusText'), kb.rdfFactory.literal(response.statusText), responseNode); // Save the response headers
1339
+ }
1580
1340
 
1581
- response.headers.forEach(function (value, header) {
1582
- kb.add(responseNode, _this10.ns.httph(header), _this10.store.rdfFactory.literal(value), responseNode);
1341
+ /* refresh Reload data from a given document
1342
+ **
1343
+ ** @param term - An RDF Named Node for the eodcument in question
1344
+ ** @param userCallback - A function userCallback(ok, message, response)
1345
+ */
1346
+ refresh(term, userCallback) {
1347
+ // sources_refresh
1348
+ this.fireCallbacks('refresh', arguments);
1349
+ this.nowOrWhenFetched(term, {
1350
+ force: true,
1351
+ clearPreviousData: true
1352
+ }, userCallback);
1353
+ }
1583
1354
 
1584
- if (header === 'content-type') {
1585
- kb.add(options.resource, _this10.ns.rdf('type'), kb.rdfFactory.namedNode(Util.mediaTypeClass(value).value), responseNode);
1586
- }
1587
- });
1588
- return responseNode;
1355
+ /* refreshIfExpired Conditional refresh if Expired
1356
+ **
1357
+ ** @param term - An RDF Named Node for the eodcument in question
1358
+ ** @param userCallback - A function userCallback(ok, message, response)
1359
+ */
1360
+ refreshIfExpired(term, userCallback) {
1361
+ let exp = this.getHeader(term, 'Expires');
1362
+ if (!exp || new Date(exp[0]).getTime() <= new Date().getTime()) {
1363
+ this.refresh(term, userCallback);
1364
+ } else {
1365
+ userCallback(true, 'Not expired', {});
1589
1366
  }
1590
- }, {
1591
- key: "objectRefresh",
1592
- value: function objectRefresh(term) {
1593
- var uris = this.store.uris(term); // Get all URIs
1594
-
1595
- if (typeof uris !== 'undefined') {
1596
- for (var i = 0; i < uris.length; i++) {
1597
- this.refresh(this.store.rdfFactory.namedNode(Uri.docpart(uris[i]))); // what about rterm?
1598
- }
1599
- }
1367
+ }
1368
+ retract(term) {
1369
+ // sources_retract
1370
+ this.store.removeMany(undefined, undefined, undefined, term);
1371
+ if (term.value) {
1372
+ delete this.requested[Uri.docpart(term.value)];
1600
1373
  }
1601
- /* refresh Reload data from a given document
1602
- **
1603
- ** @param term - An RDF Named Node for the eodcument in question
1604
- ** @param userCallback - A function userCallback(ok, message, response)
1605
- */
1606
-
1607
- }, {
1608
- key: "refresh",
1609
- value: function refresh(term, userCallback) {
1610
- // sources_refresh
1611
- this.fireCallbacks('refresh', arguments);
1612
- this.nowOrWhenFetched(term, {
1613
- force: true,
1614
- clearPreviousData: true
1615
- }, userCallback);
1616
- }
1617
- /* refreshIfExpired Conditional refresh if Expired
1618
- **
1619
- ** @param term - An RDF Named Node for the eodcument in question
1620
- ** @param userCallback - A function userCallback(ok, message, response)
1621
- */
1622
-
1623
- }, {
1624
- key: "refreshIfExpired",
1625
- value: function refreshIfExpired(term, userCallback) {
1626
- var exp = this.getHeader(term, 'Expires');
1627
-
1628
- if (!exp || new Date(exp[0]).getTime() <= new Date().getTime()) {
1629
- this.refresh(term, userCallback);
1630
- } else {
1631
- userCallback(true, 'Not expired', {});
1632
- }
1374
+ this.fireCallbacks('retract', arguments);
1375
+ }
1376
+ getState(docuri) {
1377
+ if (typeof this.requested[docuri] === 'undefined') {
1378
+ return 'unrequested';
1379
+ } else if (this.requested[docuri] === true) {
1380
+ return 'requested';
1381
+ } else if (this.requested[docuri] === 'done') {
1382
+ return 'fetched';
1383
+ } else if (this.requested[docuri] === 'redirected') {
1384
+ return this.getState(this.redirectedTo[docuri]);
1385
+ } else {
1386
+ // An non-200 HTTP error status
1387
+ return 'failed';
1633
1388
  }
1634
- }, {
1635
- key: "retract",
1636
- value: function retract(term) {
1637
- // sources_retract
1638
- this.store.removeMany(undefined, undefined, undefined, term);
1389
+ }
1390
+ isPending(docuri) {
1391
+ // sources_pending
1392
+ // doing anyStatementMatching is wasting time
1393
+ // if it's not pending: false -> flailed
1394
+ // 'done' -> done 'redirected' -> redirected
1395
+ return this.requested[docuri] === true;
1396
+ }
1397
+ unload(term) {
1398
+ this.store.removeDocument(term);
1399
+ delete this.requested[term.value]; // So it can be load2ed again
1400
+ }
1639
1401
 
1640
- if (term.value) {
1641
- delete this.requested[Uri.docpart(term.value)];
1642
- }
1402
+ addHandler(handler) {
1403
+ this.handlers.push(handler);
1404
+ handler.register(this);
1405
+ }
1406
+ retryNoCredentials(docuri, options) {
1407
+ console.log('Fetcher: CORS: RETRYING with NO CREDENTIALS for ' + options.resource);
1408
+ options.retriedWithNoCredentials = true; // protect against being called twice
1409
+
1410
+ delete this.requested[docuri]; // forget the original request happened
1411
+ delete this.fetchQueue[docuri];
1412
+ // Note: XHR property was withCredentials, but fetch property is just credentials
1413
+ let newOptions = Object.assign({}, options, {
1414
+ credentials: 'omit'
1415
+ });
1416
+ this.addStatus(options.req, 'Abort: Will retry with credentials SUPPRESSED to see if that helps');
1417
+ return this.load(docuri, newOptions);
1418
+ }
1643
1419
 
1644
- this.fireCallbacks('retract', arguments);
1645
- }
1646
- }, {
1647
- key: "getState",
1648
- value: function getState(docuri) {
1649
- if (typeof this.requested[docuri] === 'undefined') {
1650
- return 'unrequested';
1651
- } else if (this.requested[docuri] === true) {
1652
- return 'requested';
1653
- } else if (this.requested[docuri] === 'done') {
1654
- return 'fetched';
1655
- } else if (this.requested[docuri] === 'redirected') {
1656
- return this.getState(this.redirectedTo[docuri]);
1657
- } else {
1658
- // An non-200 HTTP error status
1659
- return 'failed';
1660
- }
1661
- }
1662
- }, {
1663
- key: "isPending",
1664
- value: function isPending(docuri) {
1665
- // sources_pending
1666
- // doing anyStatementMatching is wasting time
1667
- // if it's not pending: false -> flailed
1668
- // 'done' -> done 'redirected' -> redirected
1669
- return this.requested[docuri] === true;
1670
- }
1671
- }, {
1672
- key: "unload",
1673
- value: function unload(term) {
1674
- this.store.removeDocument(term);
1675
- delete this.requested[term.value]; // So it can be load2ed again
1676
- }
1677
- }, {
1678
- key: "addHandler",
1679
- value: function addHandler(handler) {
1680
- this.handlers.push(handler);
1681
- handler.register(this);
1682
- }
1683
- }, {
1684
- key: "retryNoCredentials",
1685
- value: function retryNoCredentials(docuri, options) {
1686
- console.log('Fetcher: CORS: RETRYING with NO CREDENTIALS for ' + options.resource);
1687
- options.retriedWithNoCredentials = true; // protect against being called twice
1688
-
1689
- delete this.requested[docuri]; // forget the original request happened
1690
-
1691
- delete this.fetchQueue[docuri]; // Note: XHR property was withCredentials, but fetch property is just credentials
1692
-
1693
- var newOptions = Object.assign({}, options, {
1694
- credentials: 'omit'
1695
- });
1696
- this.addStatus(options.req, 'Abort: Will retry with credentials SUPPRESSED to see if that helps');
1697
- return this.load(docuri, newOptions);
1698
- }
1699
- /**
1700
- * Tests whether a request is being made to a cross-site URI (for purposes
1701
- * of retrying with a proxy)
1702
- */
1420
+ /**
1421
+ * Tests whether a request is being made to a cross-site URI (for purposes
1422
+ * of retrying with a proxy)
1423
+ */
1424
+ isCrossSite(uri) {
1425
+ // Mashup situation, not node etc
1426
+ if (typeof document === 'undefined' || !document.location) {
1427
+ return false;
1428
+ }
1429
+ const hostpart = Uri.hostpart;
1430
+ const here = '' + document.location;
1431
+ return (hostpart(here) && hostpart(uri) && hostpart(here)) !== hostpart(uri);
1432
+ }
1703
1433
 
1704
- }, {
1705
- key: "isCrossSite",
1706
- value: function isCrossSite(uri) {
1707
- // Mashup situation, not node etc
1708
- if (typeof document === 'undefined' || !document.location) {
1709
- return false;
1434
+ /**
1435
+ * Called when there's a network error in fetch(), or a response
1436
+ * with status of 0.
1437
+ */
1438
+ handleError(response, docuri, options) {
1439
+ if (this.isCrossSite(docuri)) {
1440
+ // Make sure we haven't retried already
1441
+ if (options.credentials && options.credentials === 'include' && !options.retriedWithNoCredentials) {
1442
+ return this.retryNoCredentials(docuri, options);
1710
1443
  }
1711
1444
 
1712
- var hostpart = Uri.hostpart;
1713
- var here = '' + document.location;
1714
- return (hostpart(here) && hostpart(uri) && hostpart(here)) !== hostpart(uri);
1715
- }
1716
- /**
1717
- * Called when there's a network error in fetch(), or a response
1718
- * with status of 0.
1719
- */
1720
-
1721
- }, {
1722
- key: "handleError",
1723
- value: function handleError(response, docuri, options) {
1724
- if (this.isCrossSite(docuri)) {
1725
- // Make sure we haven't retried already
1726
- if (options.credentials && options.credentials === 'include' && !options.retriedWithNoCredentials) {
1727
- return this.retryNoCredentials(docuri, options);
1728
- } // Now attempt retry via proxy
1729
-
1730
-
1731
- var proxyUri = Fetcher.crossSiteProxy(docuri);
1732
-
1733
- if (proxyUri && !options.proxyUsed) {
1734
- console.log('web: Direct failed so trying proxy ' + proxyUri);
1735
- return this.redirectToProxy(proxyUri, options);
1736
- }
1445
+ // Now attempt retry via proxy
1446
+ let proxyUri = Fetcher.crossSiteProxy(docuri);
1447
+ if (proxyUri && !options.proxyUsed) {
1448
+ console.log('web: Direct failed so trying proxy ' + proxyUri);
1449
+ return this.redirectToProxy(proxyUri, options);
1737
1450
  }
1738
-
1739
- var message;
1740
-
1741
- if (response instanceof Error) {
1742
- message = 'Fetch error: ' + response.message;
1743
- } else {
1744
- message = response.statusText;
1745
-
1746
- if (response.responseText) {
1747
- message += " ".concat(response.responseText);
1748
- }
1749
- } // This is either not a CORS error, or retries have been made
1750
-
1751
-
1752
- return this.failFetch(options, message, response.status || 998, response);
1753
- } // deduce some things from the HTTP transaction
1754
-
1755
- }, {
1756
- key: "addType",
1757
- value: function addType(rdfType, req, kb, locURI) {
1758
- // add type to all redirected resources too
1759
- var prev = req;
1760
-
1761
- if (locURI) {
1762
- var reqURI = kb.any(prev, this.ns.link('requestedURI'));
1763
-
1764
- if (reqURI && reqURI.value !== locURI) {
1765
- kb.add(kb.rdfFactory.namedNode(locURI), this.ns.rdf('type'), rdfType, this.appNode);
1766
- }
1451
+ }
1452
+ var message;
1453
+ if (response instanceof Error) {
1454
+ message = 'Fetch error: ' + response.message;
1455
+ } else {
1456
+ message = response.statusText;
1457
+ if (response.responseText) {
1458
+ message += ` ${response.responseText}`;
1767
1459
  }
1460
+ }
1768
1461
 
1769
- for (;;) {
1770
- var doc = kb.any(prev, this.ns.link('requestedURI'));
1771
-
1772
- if (doc && doc.value) {
1773
- kb.add(kb.rdfFactory.namedNode(doc.value), this.ns.rdf('type'), rdfType, this.appNode);
1774
- } // convert Literal
1775
-
1776
-
1777
- prev = kb.any(undefined, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#redirectedRequest'), prev);
1778
-
1779
- if (!prev) {
1780
- break;
1781
- }
1782
-
1783
- var response = kb.any(prev, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#response'));
1784
-
1785
- if (!response) {
1786
- break;
1787
- }
1788
-
1789
- var redirection = kb.any(response, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/http#status'));
1790
-
1791
- if (!redirection) {
1792
- break;
1793
- } // @ts-ignore always true?
1794
-
1462
+ // This is either not a CORS error, or retries have been made
1463
+ return this.failFetch(options, message, response.status || 998, response);
1464
+ }
1795
1465
 
1796
- if (redirection !== '301' && redirection !== '302') {
1797
- break;
1798
- }
1466
+ // deduce some things from the HTTP transaction
1467
+ addType(rdfType, req, kb, locURI) {
1468
+ // add type to all redirected resources too
1469
+ let prev = req;
1470
+ if (locURI) {
1471
+ var reqURI = kb.any(prev, this.ns.link('requestedURI'));
1472
+ if (reqURI && reqURI.value !== locURI) {
1473
+ kb.add(kb.rdfFactory.namedNode(locURI), this.ns.rdf('type'), rdfType, this.appNode);
1799
1474
  }
1800
1475
  }
1801
- /**
1802
- * Handle fetch() response
1803
- */
1804
-
1805
- }, {
1806
- key: "handleResponse",
1807
- value: function handleResponse(response, docuri, options) {
1808
- var _this11 = this;
1809
-
1810
- var kb = this.store;
1811
- var headers = response.headers;
1812
- var reqNode = options.req;
1813
- var responseNode = this.saveResponseMetadata(response, options);
1814
- var contentType = this.normalizedContentType(options, headers) || '';
1815
- var contentLocation = headers.get('content-location'); // this.fireCallbacks('recv', xhr.args)
1816
- // this.fireCallbacks('headers', [{uri: docuri, headers: xhr.headers}])
1817
- // Check for masked errors (CORS, etc)
1818
-
1819
- if (response.status === 0) {
1820
- console.log('Masked error - status 0 for ' + docuri);
1821
- return this.handleError(response, docuri, options);
1476
+ for (;;) {
1477
+ const doc = kb.any(prev, this.ns.link('requestedURI'));
1478
+ if (doc && doc.value) {
1479
+ kb.add(kb.rdfFactory.namedNode(doc.value), this.ns.rdf('type'), rdfType, this.appNode);
1480
+ } // convert Literal
1481
+ prev = kb.any(undefined, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#redirectedRequest'), prev);
1482
+ if (!prev) {
1483
+ break;
1822
1484
  }
1823
-
1824
- if (response.status >= 400) {
1825
- if (response.status === 404) {
1826
- this.nonexistent[options.original.value] = true;
1827
- this.nonexistent[docuri] = true;
1828
- }
1829
-
1830
- return this.saveErrorResponse(response, responseNode).then(function () {
1831
- var errorMessage = options.resource + ' ' + response.statusText;
1832
- return _this11.failFetch(options, errorMessage, response.status, response);
1833
- });
1485
+ var response = kb.any(prev, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#response'));
1486
+ if (!response) {
1487
+ break;
1834
1488
  }
1835
-
1836
- var diffLocation = null;
1837
- var absContentLocation = null;
1838
-
1839
- if (contentLocation) {
1840
- absContentLocation = Uri.join(contentLocation, docuri);
1841
-
1842
- if (absContentLocation !== docuri) {
1843
- diffLocation = absContentLocation;
1844
- }
1845
- }
1846
-
1847
- if (response.status === 200) {
1848
- this.addType(this.ns.link('Document'), reqNode, kb, docuri);
1849
-
1850
- if (diffLocation) {
1851
- this.addType(this.ns.link('Document'), reqNode, kb, diffLocation);
1852
- } // Before we parse new data clear old but only on 200
1853
-
1854
-
1855
- if (options.clearPreviousData) {
1856
- kb.removeDocument(options.resource);
1857
- }
1858
-
1859
- var isImage = contentType.includes('image/') || contentType.includes('application/pdf');
1860
-
1861
- if (contentType && isImage) {
1862
- this.addType(kb.rdfFactory.namedNode('http://purl.org/dc/terms/Image'), reqNode, kb, docuri);
1863
-
1864
- if (diffLocation) {
1865
- this.addType(kb.rdfFactory.namedNode('http://purl.org/dc/terms/Image'), reqNode, kb, diffLocation);
1866
- }
1867
- }
1868
- } // If we have already got the thing at this location, abort
1869
-
1870
-
1871
- if (contentLocation) {
1872
- if (!options.force && diffLocation && this.requested[absContentLocation] === 'done') {
1873
- // we have already fetched this
1874
- // should we smush too?
1875
- // log.info("HTTP headers indicate we have already" + " retrieved " +
1876
- // xhr.resource + " as " + absContentLocation + ". Aborting.")
1877
- return this.doneFetch(options, response);
1878
- }
1879
-
1880
- this.requested[absContentLocation] = true;
1489
+ var redirection = kb.any(response, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/http#status'));
1490
+ if (!redirection) {
1491
+ break;
1881
1492
  }
1882
-
1883
- this.parseLinkHeader(headers.get('link'), options.original, reqNode);
1884
- var handler = this.handlerForContentType(contentType, response);
1885
-
1886
- if (!handler) {
1887
- // Not a problem, we just don't extract data
1888
- this.addStatus(reqNode, 'Fetch over. No data handled.');
1889
- return this.doneFetch(options, response);
1493
+ // @ts-ignore always true?
1494
+ if (redirection !== '301' && redirection !== '302') {
1495
+ break;
1890
1496
  }
1891
-
1892
- return response.text() // @ts-ignore Types seem right
1893
- .then(function (responseText) {
1894
- response.responseText = responseText;
1895
- return handler.parse(_this11, responseText, options, response);
1896
- });
1897
1497
  }
1898
- }, {
1899
- key: "saveErrorResponse",
1900
- value: function saveErrorResponse(response, responseNode) {
1901
- var _this12 = this;
1498
+ }
1902
1499
 
1903
- var kb = this.store;
1904
- return response.text().then(function (content) {
1905
- if (content.length > 10) {
1906
- kb.add(responseNode, _this12.ns.http('content'), kb.rdfFactory.literal(content), responseNode);
1907
- }
1500
+ /**
1501
+ * Handle fetch() response
1502
+ */
1503
+ handleResponse(response, docuri, options) {
1504
+ const kb = this.store;
1505
+ const headers = response.headers;
1506
+ const reqNode = options.req;
1507
+ const responseNode = this.saveResponseMetadata(response, options);
1508
+ const contentType = this.normalizedContentType(options, headers) || '';
1509
+ let contentLocation = headers.get('content-location');
1510
+
1511
+ // this.fireCallbacks('recv', xhr.args)
1512
+ // this.fireCallbacks('headers', [{uri: docuri, headers: xhr.headers}])
1513
+
1514
+ // Check for masked errors (CORS, etc)
1515
+ if (response.status === 0) {
1516
+ console.log('Masked error - status 0 for ' + docuri);
1517
+ return this.handleError(response, docuri, options);
1518
+ }
1519
+ if (response.status >= 400) {
1520
+ if (response.status === 404) {
1521
+ this.nonexistent[options.original.value] = true;
1522
+ this.nonexistent[docuri] = true;
1523
+ }
1524
+ return this.saveErrorResponse(response, responseNode).then(() => {
1525
+ let errorMessage = options.resource + ' ' + response.statusText;
1526
+ return this.failFetch(options, errorMessage, response.status, response);
1908
1527
  });
1909
1528
  }
1910
- }, {
1911
- key: "handlerForContentType",
1912
- value: function handlerForContentType(contentType, response) {
1913
- if (!contentType) {
1914
- return null;
1529
+ var diffLocation = null;
1530
+ var absContentLocation = null;
1531
+ if (contentLocation) {
1532
+ absContentLocation = Uri.join(contentLocation, docuri);
1533
+ if (absContentLocation !== docuri) {
1534
+ diffLocation = absContentLocation;
1915
1535
  }
1916
-
1917
- var Handler = this.handlers.find(function (handler) {
1918
- return contentType.match(handler.pattern);
1919
- }); // @ts-ignore in practice all Handlers have constructors.
1920
-
1921
- return Handler ? new Handler(response) : null;
1922
1536
  }
1923
- }, {
1924
- key: "guessContentType",
1925
- value: function guessContentType(uri) {
1926
- return CONTENT_TYPE_BY_EXT[uri.split('.').pop()];
1927
- }
1928
- }, {
1929
- key: "normalizedContentType",
1930
- value: function normalizedContentType(options, headers) {
1931
- if (options.forceContentType) {
1932
- return options.forceContentType;
1537
+ if (response.status === 200) {
1538
+ this.addType(this.ns.link('Document'), reqNode, kb, docuri);
1539
+ if (diffLocation) {
1540
+ this.addType(this.ns.link('Document'), reqNode, kb, diffLocation);
1933
1541
  }
1934
1542
 
1935
- var contentType = headers.get('content-type');
1936
-
1937
- if (!contentType || contentType.includes('application/octet-stream')) {
1938
- var guess = this.guessContentType(options.resource.value);
1939
-
1940
- if (guess) {
1941
- return guess;
1942
- }
1543
+ // Before we parse new data clear old but only on 200
1544
+ if (options.clearPreviousData) {
1545
+ kb.removeDocument(options.resource);
1943
1546
  }
1944
-
1945
- var protocol = Uri.protocol(options.resource.value);
1946
-
1947
- if (!contentType && ['file', 'chrome'].includes(protocol)) {
1948
- return 'text/xml';
1949
- }
1950
-
1951
- return contentType;
1952
- }
1953
- /**
1954
- * Sends a new request to the specified uri. (Extracted from `onerrorFactory()`)
1955
- */
1956
-
1957
- }, {
1958
- key: "redirectToProxy",
1959
- value: function redirectToProxy(newURI, options) {
1960
- var _this13 = this;
1961
-
1962
- this.addStatus(options.req, 'BLOCKED -> Cross-site Proxy to <' + newURI + '>');
1963
- options.proxyUsed = true;
1964
- var kb = this.store;
1965
- var oldReq = options.req; // request metadata blank node
1966
-
1967
- if (!options.noMeta) {
1968
- kb.add(oldReq, this.ns.link('redirectedTo'), kb.rdfFactory.namedNode(newURI), oldReq);
1969
- this.addStatus(oldReq, 'redirected to new request'); // why
1970
- }
1971
-
1972
- this.requested[options.resource.value] = 'redirected';
1973
- this.redirectedTo[options.resource.value] = newURI;
1974
- var newOptions = Object.assign({}, options);
1975
- newOptions.baseURI = options.resource.value;
1976
- return this.fetchUri(newURI, newOptions).then(function (response) {
1977
- if (!newOptions.noMeta) {
1978
- kb.add(oldReq, _this13.ns.link('redirectedRequest'), newOptions.req, _this13.appNode);
1547
+ let isImage = contentType.includes('image/') || contentType.includes('application/pdf');
1548
+ if (contentType && isImage) {
1549
+ this.addType(kb.rdfFactory.namedNode('http://purl.org/dc/terms/Image'), reqNode, kb, docuri);
1550
+ if (diffLocation) {
1551
+ this.addType(kb.rdfFactory.namedNode('http://purl.org/dc/terms/Image'), reqNode, kb, diffLocation);
1979
1552
  }
1980
-
1981
- return response;
1982
- });
1983
- }
1984
- }, {
1985
- key: "setRequestTimeout",
1986
- value: function setRequestTimeout(uri, options) {
1987
- var _this14 = this;
1988
-
1989
- return new Promise(function (resolve) {
1990
- _this14.timeouts[uri] = (_this14.timeouts[uri] || []).concat(setTimeout(function () {
1991
- if (_this14.isPending(uri) && !options.retriedWithNoCredentials && !options.proxyUsed) {
1992
- resolve(_this14.failFetch(options, "Request to ".concat(uri, " timed out"), 'timeout'));
1993
- }
1994
- }, _this14.timeout));
1995
- });
1996
- }
1997
- }, {
1998
- key: "addFetchCallback",
1999
- value: function addFetchCallback(uri, callback) {
2000
- if (!this.fetchCallbacks[uri]) {
2001
- this.fetchCallbacks[uri] = [callback];
2002
- } else {
2003
- this.fetchCallbacks[uri].push(callback);
2004
1553
  }
2005
1554
  }
2006
- }, {
2007
- key: "acceptString",
2008
- value: function acceptString() {
2009
- var acceptstring = '';
2010
-
2011
- for (var mediaType in this.mediatypes) {
2012
- if (acceptstring !== '') {
2013
- acceptstring += ', ';
2014
- }
2015
-
2016
- acceptstring += mediaType;
2017
-
2018
- for (var property in this.mediatypes[mediaType]) {
2019
- acceptstring += ';' + property + '=' + this.mediatypes[mediaType][property];
2020
- }
2021
- }
2022
-
2023
- return acceptstring;
2024
- } // var updatesVia = new $rdf.UpdatesVia(this) // Subscribe to headers
2025
- // @@@@@@@@ This is turned off because it causes a websocket to be set up for ANY fetch
2026
- // whether we want to track it ot not. including ontologies loaed though the XSSproxy
2027
1555
 
2028
- }], [{
2029
- key: "crossSiteProxy",
2030
- value: function crossSiteProxy(uri) {
2031
- if (Fetcher.crossSiteProxyTemplate) {
2032
- return Fetcher.crossSiteProxyTemplate.replace('{uri}', encodeURIComponent(uri));
2033
- } else {
2034
- return undefined;
1556
+ // If we have already got the thing at this location, abort
1557
+ if (contentLocation) {
1558
+ if (!options.force && diffLocation && this.requested[absContentLocation] === 'done') {
1559
+ // we have already fetched this
1560
+ // should we smush too?
1561
+ // log.info("HTTP headers indicate we have already" + " retrieved " +
1562
+ // xhr.resource + " as " + absContentLocation + ". Aborting.")
1563
+ return this.doneFetch(options, response);
2035
1564
  }
2036
- }
2037
- }, {
2038
- key: "offlineOverride",
2039
- value: function offlineOverride(uri) {
2040
- // Map the URI to a localhost proxy if we are running on localhost
2041
- // This is used for working offline, e.g. on planes.
2042
- // Is the script itself is running in localhost, then access all
2043
- // data in a localhost mirror.
2044
- // Do not remove without checking with TimBL
2045
- var requestedURI = uri;
2046
- var UI;
2047
-
2048
- if (typeof window !== 'undefined' && window.panes && (UI = window.panes.UI) && UI.preferences && UI.preferences.get('offlineModeUsingLocalhost')) {
2049
- if (requestedURI.slice(0, 7) === 'http://' && requestedURI.slice(7, 17) !== 'localhost/') {
2050
- requestedURI = 'http://localhost/' + requestedURI.slice(7);
2051
-
2052
- _log.default.warn('Localhost kludge for offline use: actually getting <' + requestedURI + '>');
2053
- } else {// log.warn("Localhost kludge NOT USED <" + requestedURI + ">")
2054
- }
2055
- } else {// log.warn("Localhost kludge OFF offline use: actually getting <" +
2056
- // requestedURI + ">")
1565
+ this.requested[absContentLocation] = true;
1566
+ }
1567
+ this.parseLinkHeader(headers.get('link'), options.original, reqNode);
1568
+ let handler = this.handlerForContentType(contentType, response);
1569
+ if (!handler) {
1570
+ // Not a problem, we just don't extract data
1571
+ this.addStatus(reqNode, 'Fetch over. No data handled.');
1572
+ return this.doneFetch(options, response);
1573
+ }
1574
+ return response.text()
1575
+ // @ts-ignore Types seem right
1576
+ .then(responseText => {
1577
+ response.responseText = responseText;
1578
+ return handler.parse(this, responseText, options, response);
1579
+ });
1580
+ }
1581
+ saveErrorResponse(response, responseNode) {
1582
+ let kb = this.store;
1583
+ return response.text().then(content => {
1584
+ if (content.length > 10) {
1585
+ kb.add(responseNode, this.ns.http('content'), kb.rdfFactory.literal(content), responseNode);
2057
1586
  }
2058
-
2059
- return requestedURI;
1587
+ });
1588
+ }
1589
+ handlerForContentType(contentType, response) {
1590
+ if (!contentType) {
1591
+ return null;
2060
1592
  }
2061
- }, {
2062
- key: "proxyIfNecessary",
2063
- value: function proxyIfNecessary(uri) {
2064
- var UI;
2065
-
2066
- if (typeof window !== 'undefined' && window.panes && (UI = window.panes.UI) && UI.isExtension) {
2067
- return uri;
2068
- } // Extension does not need proxy
2069
-
2070
-
2071
- if (typeof $SolidTestEnvironment !== 'undefined' && $SolidTestEnvironment.localSiteMap) {
2072
- // nested dictionaries of URI parts from origin down
2073
- var hostpath = uri.split('/').slice(2); // the bit after the //
2074
-
2075
- var lookup = function lookup(parts, index) {
2076
- var z = index[parts.shift()];
2077
-
2078
- if (!z) {
2079
- return null;
2080
- }
2081
-
2082
- if (typeof z === 'string') {
2083
- return z + parts.join('/');
2084
- }
2085
-
2086
- if (!parts) {
2087
- return null;
2088
- }
2089
-
2090
- return lookup(parts, z);
2091
- };
2092
-
2093
- var y = lookup(hostpath, $SolidTestEnvironment.localSiteMap);
2094
-
2095
- if (y) {
2096
- return y;
2097
- }
2098
- } // browser does 2014 on as https browser script not trusted
2099
- // If the web app origin is https: then the mixed content rules
2100
- // prevent it loading insecure http: stuff so we need proxy.
2101
-
1593
+ let Handler = this.handlers.find(handler => {
1594
+ return contentType.match(handler.pattern);
1595
+ });
2102
1596
 
2103
- if (Fetcher.crossSiteProxyTemplate && typeof document !== 'undefined' && document.location && ('' + document.location).slice(0, 6) === 'https:' && // origin is secure
2104
- uri.slice(0, 5) === 'http:') {
2105
- // requested data is not
2106
- return Fetcher.crossSiteProxyTemplate.replace('{uri}', encodeURIComponent(uri));
1597
+ // @ts-ignore in practice all Handlers have constructors.
1598
+ return Handler ? new Handler(response) : null;
1599
+ }
1600
+ guessContentType(uri) {
1601
+ return CONTENT_TYPE_BY_EXT[uri.split('.').pop()];
1602
+ }
1603
+ normalizedContentType(options, headers) {
1604
+ if (options.forceContentType) {
1605
+ return options.forceContentType;
1606
+ }
1607
+ let contentType = headers.get('content-type');
1608
+ if (!contentType || contentType.includes('application/octet-stream')) {
1609
+ let guess = this.guessContentType(options.resource.value);
1610
+ if (guess) {
1611
+ return guess;
2107
1612
  }
2108
-
2109
- return uri;
2110
1613
  }
2111
- /**
2112
- * Tests whether the uri's protocol is supported by the Fetcher.
2113
- * @param uri
2114
- */
2115
-
2116
- }, {
2117
- key: "unsupportedProtocol",
2118
- value: function unsupportedProtocol(uri) {
2119
- var pcol = Uri.protocol(uri);
2120
- return pcol === 'tel' || pcol === 'mailto' || pcol === 'urn';
1614
+ let protocol = Uri.protocol(options.resource.value);
1615
+ if (!contentType && ['file', 'chrome'].includes(protocol)) {
1616
+ return 'text/xml';
2121
1617
  }
2122
- /** Decide on credentials using old XXHR api or new fetch() one
2123
- * @param requestedURI
2124
- * @param options
2125
- */
1618
+ return contentType;
1619
+ }
2126
1620
 
2127
- }, {
2128
- key: "setCredentials",
2129
- value: function setCredentials(requestedURI) {
2130
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2131
-
2132
- // 2014 CORS problem:
2133
- // XMLHttpRequest cannot load http://www.w3.org/People/Berners-Lee/card.
2134
- // A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin'
2135
- // header when the credentials flag is true.
2136
- // @ Many ontology files under http: and need CORS wildcard ->
2137
- // can't have credentials
2138
- if (options.credentials === undefined) {
2139
- // Caller using new fetch convention
2140
- if (options.withCredentials !== undefined) {
2141
- // XHR style is what Fetcher specified before
2142
- options.credentials = options.withCredentials ? 'include' : 'omit';
2143
- } else {
2144
- options.credentials = 'include'; // default is to be logged on
1621
+ /**
1622
+ * Sends a new request to the specified uri. (Extracted from `onerrorFactory()`)
1623
+ */
1624
+ redirectToProxy(newURI, options) {
1625
+ this.addStatus(options.req, 'BLOCKED -> Cross-site Proxy to <' + newURI + '>');
1626
+ options.proxyUsed = true;
1627
+ const kb = this.store;
1628
+ const oldReq = options.req; // request metadata blank node
1629
+
1630
+ if (!options.noMeta) {
1631
+ kb.add(oldReq, this.ns.link('redirectedTo'), kb.rdfFactory.namedNode(newURI), oldReq);
1632
+ this.addStatus(oldReq, 'redirected to new request'); // why
1633
+ }
1634
+
1635
+ this.requested[options.resource.value] = 'redirected';
1636
+ this.redirectedTo[options.resource.value] = newURI;
1637
+ let newOptions = Object.assign({}, options);
1638
+ newOptions.baseURI = options.resource.value;
1639
+ return this.fetchUri(newURI, newOptions).then(response => {
1640
+ if (!newOptions.noMeta) {
1641
+ kb.add(oldReq, this.ns.link('redirectedRequest'), newOptions.req, this.appNode);
1642
+ }
1643
+ return response;
1644
+ });
1645
+ }
1646
+ setRequestTimeout(uri, options) {
1647
+ return new Promise(resolve => {
1648
+ this.timeouts[uri] = (this.timeouts[uri] || []).concat(setTimeout(() => {
1649
+ if (this.isPending(uri) && !options.retriedWithNoCredentials && !options.proxyUsed) {
1650
+ resolve(this.failFetch(options, `Request to ${uri} timed out`, 'timeout'));
2145
1651
  }
1652
+ }, this.timeout));
1653
+ });
1654
+ }
1655
+ addFetchCallback(uri, callback) {
1656
+ if (!this.fetchCallbacks[uri]) {
1657
+ this.fetchCallbacks[uri] = [callback];
1658
+ } else {
1659
+ this.fetchCallbacks[uri].push(callback);
1660
+ }
1661
+ }
1662
+ acceptString() {
1663
+ let acceptstring = '';
1664
+ for (let mediaType in this.mediatypes) {
1665
+ if (acceptstring !== '') {
1666
+ acceptstring += ', ';
1667
+ }
1668
+ acceptstring += mediaType;
1669
+ for (let property in this.mediatypes[mediaType]) {
1670
+ acceptstring += ';' + property + '=' + this.mediatypes[mediaType][property];
2146
1671
  }
2147
1672
  }
2148
- }]);
2149
- return Fetcher;
2150
- }();
2151
-
1673
+ return acceptstring;
1674
+ }
1675
+ // var updatesVia = new $rdf.UpdatesVia(this) // Subscribe to headers
1676
+ // @@@@@@@@ This is turned off because it causes a websocket to be set up for ANY fetch
1677
+ // whether we want to track it ot not. including ontologies loaed though the XSSproxy
1678
+ }
2152
1679
  exports.default = Fetcher;
2153
1680
  (0, _defineProperty2.default)(Fetcher, "HANDLERS", void 0);
2154
1681
  (0, _defineProperty2.default)(Fetcher, "CONTENT_TYPE_BY_EXT", void 0);