rdflib 2.2.22 → 2.2.23-1c672b7b

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 (100) hide show
  1. package/dist/rdflib.min.js +1 -1
  2. package/dist/rdflib.min.js.LICENSE.txt +4 -0
  3. package/dist/rdflib.min.js.map +1 -1
  4. package/esm/blank-node.js +90 -61
  5. package/esm/class-order.js +1 -1
  6. package/esm/collection.js +106 -70
  7. package/esm/default-graph.js +33 -13
  8. package/esm/empty.js +26 -8
  9. package/esm/factories/canonical-data-factory.js +30 -33
  10. package/esm/factories/extended-term-factory.js +14 -18
  11. package/esm/factories/factory-types.js +1 -1
  12. package/esm/factories/rdflib-data-factory.js +11 -9
  13. package/esm/fetcher.js +1644 -1355
  14. package/esm/formula.js +740 -632
  15. package/esm/index.js +52 -33
  16. package/esm/jsonldparser.js +35 -19
  17. package/esm/jsonparser.js +1 -1
  18. package/esm/lists.js +86 -38
  19. package/esm/literal.js +157 -120
  20. package/esm/log.js +7 -7
  21. package/esm/n3parser.js +1088 -1004
  22. package/esm/named-node.js +99 -69
  23. package/esm/namespace.js +4 -2
  24. package/esm/node-internal.js +98 -74
  25. package/esm/node.js +1 -1
  26. package/esm/parse.js +3 -3
  27. package/esm/patch-parser.js +1 -1
  28. package/esm/query.js +16 -15
  29. package/esm/rdfaparser.js +846 -781
  30. package/esm/rdfxmlparser.js +365 -348
  31. package/esm/serialize.js +4 -11
  32. package/esm/serializer.js +886 -821
  33. package/esm/statement.js +72 -52
  34. package/esm/store.js +924 -822
  35. package/esm/types.js +21 -21
  36. package/esm/update-manager.js +983 -882
  37. package/esm/updates-via.js +134 -104
  38. package/esm/uri.js +3 -3
  39. package/esm/utils/default-graph-uri.js +2 -2
  40. package/esm/utils/terms.js +5 -4
  41. package/esm/utils-js.js +5 -5
  42. package/esm/utils.js +6 -6
  43. package/esm/variable.js +58 -32
  44. package/esm/xsd.js +2 -2
  45. package/lib/blank-node.js +88 -60
  46. package/lib/class-order.js +1 -1
  47. package/lib/collection.js +104 -69
  48. package/lib/default-graph.js +32 -13
  49. package/lib/empty.js +25 -8
  50. package/lib/factories/canonical-data-factory.js +32 -35
  51. package/lib/factories/extended-term-factory.js +14 -18
  52. package/lib/factories/factory-types.js +1 -1
  53. package/lib/factories/rdflib-data-factory.js +11 -9
  54. package/lib/fetcher.js +1646 -1385
  55. package/lib/formula.js +739 -632
  56. package/lib/index.d.ts +1 -2
  57. package/lib/index.js +88 -70
  58. package/lib/jsonldparser.js +35 -19
  59. package/lib/jsonparser.js +1 -1
  60. package/lib/lists.js +86 -54
  61. package/lib/literal.js +156 -120
  62. package/lib/log.js +7 -7
  63. package/lib/n3parser.d.ts +1 -0
  64. package/lib/n3parser.js +1092 -1006
  65. package/lib/named-node.js +98 -69
  66. package/lib/namespace.js +4 -2
  67. package/lib/node-internal.js +96 -73
  68. package/lib/node.js +1 -1
  69. package/lib/parse.js +6 -5
  70. package/lib/patch-parser.js +1 -1
  71. package/lib/query.js +18 -19
  72. package/lib/rdfaparser.js +848 -783
  73. package/lib/rdfxmlparser.js +366 -350
  74. package/lib/serialize.js +4 -13
  75. package/lib/serializer.d.ts +1 -0
  76. package/lib/serializer.js +890 -825
  77. package/lib/statement.js +74 -54
  78. package/lib/store.js +926 -844
  79. package/lib/types.js +21 -21
  80. package/lib/update-manager.d.ts +1 -1
  81. package/lib/update-manager.js +959 -865
  82. package/lib/updates-via.js +134 -105
  83. package/lib/uri.js +3 -3
  84. package/lib/utils/default-graph-uri.js +2 -2
  85. package/lib/utils/terms.js +6 -4
  86. package/lib/utils-js.js +9 -8
  87. package/lib/utils.js +6 -6
  88. package/lib/variable.js +60 -34
  89. package/lib/xsd.js +2 -2
  90. package/package.json +20 -19
  91. package/src/index.ts +0 -2
  92. package/src/jsonldparser.js +13 -4
  93. package/src/n3parser.js +12 -4
  94. package/src/serialize.ts +3 -10
  95. package/src/serializer.js +24 -0
  96. package/src/update-manager.ts +8 -2
  97. package/esm/convert.js +0 -60
  98. package/lib/convert.d.ts +0 -2
  99. package/lib/convert.js +0 -71
  100. package/src/convert.js +0 -70
@@ -1,4 +1,10 @@
1
+ import _typeof from "@babel/runtime/helpers/typeof";
2
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
+ import _createClass from "@babel/runtime/helpers/createClass";
1
4
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
6
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
7
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
2
8
  /* @file Update Manager Class
3
9
  **
4
10
  ** 2007-07-15 originall sparl update module by Joe Presbrey <presbrey@mit.edu>
@@ -19,7 +25,7 @@ import { termValue } from './utils/termValue';
19
25
  * the Update Manager provides functionality for making small patches in real time,
20
26
  * and also looking out for concurrent updates from other agents
21
27
  */
22
- export default class UpdateManager {
28
+ var UpdateManager = /*#__PURE__*/function () {
23
29
  /** Index of objects for coordinating incoming and outgoing patches */
24
30
 
25
31
  /** Object of namespaces */
@@ -27,7 +33,8 @@ export default class UpdateManager {
27
33
  /**
28
34
  * @param store - The quadstore to store data and metadata. Created if not passed.
29
35
  */
30
- constructor(store) {
36
+ function UpdateManager(store) {
37
+ _classCallCheck(this, UpdateManager);
31
38
  _defineProperty(this, "store", void 0);
32
39
  _defineProperty(this, "ifps", void 0);
33
40
  _defineProperty(this, "fps", void 0);
@@ -55,968 +62,1062 @@ export default class UpdateManager {
55
62
  this.ns.owl = Namespace('http://www.w3.org/2002/07/owl#');
56
63
  this.patchControl = [];
57
64
  }
58
- patchControlFor(doc) {
59
- if (!this.patchControl[doc.value]) {
60
- this.patchControl[doc.value] = [];
65
+ _createClass(UpdateManager, [{
66
+ key: "patchControlFor",
67
+ value: function patchControlFor(doc) {
68
+ if (!this.patchControl[doc.value]) {
69
+ this.patchControl[doc.value] = [];
70
+ }
71
+ return this.patchControl[doc.value];
72
+ }
73
+ }, {
74
+ key: "isHttpUri",
75
+ value: function isHttpUri(uri) {
76
+ return uri.slice(0, 4) === 'http';
61
77
  }
62
- return this.patchControl[doc.value];
63
- }
64
- isHttpUri(uri) {
65
- return uri.slice(0, 4) === 'http';
66
- }
67
78
 
68
- /**
69
- * Tests whether a file is editable.
70
- * If the file has a specific annotation that it is machine written,
71
- * for safety, it is editable (this doesn't actually check for write access)
72
- * If the file has wac-allow and accept patch headers, those are respected.
73
- * and local write access is determined by those headers.
74
- * This version only looks at past HTTP requests, does not make new ones.
75
- *
76
- * @returns The method string SPARQL or DAV or
77
- * LOCALFILE or false if known, undefined if not known.
78
- */
79
- editable(uri, kb) {
80
- if (!uri) {
81
- return false; // Eg subject is bnode, no known doc to write to
82
- }
83
-
84
- if (!kb) {
85
- kb = this.store;
86
- }
87
- uri = termValue(uri);
88
- if (!this.isHttpUri(uri)) {
89
- if (kb.holds(this.store.rdfFactory.namedNode(uri), this.store.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), this.store.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#MachineEditableDocument'))) {
90
- return 'LOCALFILE';
91
- }
92
- }
93
- var request;
94
- var definitive = false;
95
- // @ts-ignore passes a string to kb.each, which expects a term. Should this work?
96
- var requests = kb.each(undefined, this.ns.link('requestedURI'), docpart(uri));
97
- var method;
98
- for (var r = 0; r < requests.length; r++) {
99
- request = requests[r];
100
- if (request !== undefined) {
101
- var response = kb.any(request, this.ns.link('response'));
79
+ /**
80
+ * Tests whether a file is editable.
81
+ * If the file has a specific annotation that it is machine written,
82
+ * for safety, it is editable (this doesn't actually check for write access)
83
+ * If the file has wac-allow and accept patch headers, those are respected.
84
+ * and local write access is determined by those headers.
85
+ * This version only looks at past HTTP requests, does not make new ones.
86
+ *
87
+ * @returns The method string SPARQL or DAV or
88
+ * LOCALFILE or false if known, undefined if not known.
89
+ */
90
+ }, {
91
+ key: "editable",
92
+ value: function editable(uri, kb) {
93
+ if (!uri) {
94
+ return false; // Eg subject is bnode, no known doc to write to
95
+ }
96
+
97
+ if (!kb) {
98
+ kb = this.store;
99
+ }
100
+ uri = termValue(uri);
101
+ if (!this.isHttpUri(uri)) {
102
+ if (kb.holds(this.store.rdfFactory.namedNode(uri), this.store.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), this.store.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#MachineEditableDocument'))) {
103
+ return 'LOCALFILE';
104
+ }
105
+ }
106
+ var request;
107
+ var definitive = false;
108
+ // @ts-ignore passes a string to kb.each, which expects a term. Should this work?
109
+ var requests = kb.each(undefined, this.ns.link('requestedURI'), docpart(uri));
110
+ var method;
111
+ for (var r = 0; r < requests.length; r++) {
112
+ request = requests[r];
102
113
  if (request !== undefined) {
103
- var wacAllow = kb.anyValue(response, this.ns.httph('wac-allow'));
104
- if (wacAllow) {
105
- for (var bit of wacAllow.split(',')) {
106
- var lr = bit.split('=');
107
- if (lr[0].includes('user') && !lr[1].includes('write') && !lr[1].includes('append')) {
108
- // console.log(' editable? excluded by WAC-Allow: ', wacAllow)
109
- return false;
114
+ var response = kb.any(request, this.ns.link('response'));
115
+ if (request !== undefined) {
116
+ var wacAllow = kb.anyValue(response, this.ns.httph('wac-allow'));
117
+ if (wacAllow) {
118
+ var _iterator = _createForOfIteratorHelper(wacAllow.split(',')),
119
+ _step;
120
+ try {
121
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
122
+ var bit = _step.value;
123
+ var lr = bit.split('=');
124
+ if (lr[0].includes('user') && !lr[1].includes('write') && !lr[1].includes('append')) {
125
+ // console.log(' editable? excluded by WAC-Allow: ', wacAllow)
126
+ return false;
127
+ }
128
+ }
129
+ } catch (err) {
130
+ _iterator.e(err);
131
+ } finally {
132
+ _iterator.f();
110
133
  }
111
134
  }
112
- }
113
- var acceptPatch = kb.each(response, this.ns.httph('accept-patch'));
114
- if (acceptPatch.length) {
115
- for (let i = 0; i < acceptPatch.length; i++) {
116
- method = acceptPatch[i].value.trim();
117
- if (method.indexOf('application/sparql-update') >= 0) return 'SPARQL';
118
- if (method.indexOf('application/sparql-update-single-match') >= 0) return 'SPARQL';
119
- }
120
- }
121
- var authorVia = kb.each(response, this.ns.httph('ms-author-via'));
122
- if (authorVia.length) {
123
- for (let i = 0; i < authorVia.length; i++) {
124
- method = authorVia[i].value.trim();
125
- if (method.indexOf('SPARQL') >= 0) {
126
- return 'SPARQL';
135
+ var acceptPatch = kb.each(response, this.ns.httph('accept-patch'));
136
+ if (acceptPatch.length) {
137
+ for (var i = 0; i < acceptPatch.length; i++) {
138
+ method = acceptPatch[i].value.trim();
139
+ if (method.indexOf('application/sparql-update') >= 0) return 'SPARQL';
140
+ if (method.indexOf('application/sparql-update-single-match') >= 0) return 'SPARQL';
127
141
  }
128
- if (method.indexOf('DAV') >= 0) {
129
- return 'DAV';
142
+ }
143
+ var authorVia = kb.each(response, this.ns.httph('ms-author-via'));
144
+ if (authorVia.length) {
145
+ for (var _i = 0; _i < authorVia.length; _i++) {
146
+ method = authorVia[_i].value.trim();
147
+ if (method.indexOf('SPARQL') >= 0) {
148
+ return 'SPARQL';
149
+ }
150
+ if (method.indexOf('DAV') >= 0) {
151
+ return 'DAV';
152
+ }
130
153
  }
131
154
  }
132
- }
133
- if (!this.isHttpUri(uri)) {
134
- if (!wacAllow) return false;else return 'LOCALFILE';
135
- }
136
- var status = kb.each(response, this.ns.http('status'));
137
- if (status.length) {
138
- for (let i = 0; i < status.length; i++) {
139
- // @ts-ignore since statuses should be TFTerms, this should always be false
140
- if (status[i] === 200 || status[i] === 404) {
141
- definitive = true;
142
- // return false // A definitive answer
155
+ if (!this.isHttpUri(uri)) {
156
+ if (!wacAllow) return false;else return 'LOCALFILE';
157
+ }
158
+ var status = kb.each(response, this.ns.http('status'));
159
+ if (status.length) {
160
+ for (var _i2 = 0; _i2 < status.length; _i2++) {
161
+ // @ts-ignore since statuses should be TFTerms, this should always be false
162
+ if (status[_i2] === 200 || status[_i2] === 404) {
163
+ definitive = true;
164
+ // return false // A definitive answer
165
+ }
143
166
  }
144
167
  }
168
+ } else {
169
+ // console.log('UpdateManager.editable: No response for ' + uri + '\n')
145
170
  }
146
- } else {
147
- // console.log('UpdateManager.editable: No response for ' + uri + '\n')
148
171
  }
149
172
  }
150
- }
151
- if (requests.length === 0) {
152
- // console.log('UpdateManager.editable: No request for ' + uri + '\n')
153
- } else {
154
- if (definitive) {
155
- return false; // We have got a request and it did NOT say editable => not editable
173
+ if (requests.length === 0) {
174
+ // console.log('UpdateManager.editable: No request for ' + uri + '\n')
175
+ } else {
176
+ if (definitive) {
177
+ return false; // We have got a request and it did NOT say editable => not editable
178
+ }
156
179
  }
180
+ // console.log('UpdateManager.editable: inconclusive for ' + uri + '\n')
181
+ return undefined; // We don't know (yet) as we haven't had a response (yet)
182
+ }
183
+ }, {
184
+ key: "anonymize",
185
+ value: function anonymize(obj) {
186
+ return obj.toNT().substr(0, 2) === '_:' && this.mentioned(obj) ? '?' + obj.toNT().substr(2) : obj.toNT();
187
+ }
188
+ }, {
189
+ key: "anonymizeNT",
190
+ value: function anonymizeNT(stmt) {
191
+ return this.anonymize(stmt.subject) + ' ' + this.anonymize(stmt.predicate) + ' ' + this.anonymize(stmt.object) + ' .';
192
+ }
193
+ }, {
194
+ key: "nTriples",
195
+ value: function nTriples(stmt) {
196
+ return "".concat(stmt.subject.toNT(), " ").concat(stmt.predicate.toNT(), " ").concat(stmt.object.toNT(), " .");
157
197
  }
158
- // console.log('UpdateManager.editable: inconclusive for ' + uri + '\n')
159
- return undefined; // We don't know (yet) as we haven't had a response (yet)
160
- }
161
-
162
- anonymize(obj) {
163
- return obj.toNT().substr(0, 2) === '_:' && this.mentioned(obj) ? '?' + obj.toNT().substr(2) : obj.toNT();
164
- }
165
- anonymizeNT(stmt) {
166
- return this.anonymize(stmt.subject) + ' ' + this.anonymize(stmt.predicate) + ' ' + this.anonymize(stmt.object) + ' .';
167
- }
168
- nTriples(stmt) {
169
- return `${stmt.subject.toNT()} ${stmt.predicate.toNT()} ${stmt.object.toNT()} .`;
170
- }
171
-
172
- /**
173
- * Returns a list of all bnodes occurring in a statement
174
- * @private
175
- */
176
- statementBnodes(st) {
177
- return [st.subject, st.predicate, st.object].filter(function (x) {
178
- return isBlankNode(x);
179
- });
180
- }
181
198
 
182
- /**
183
- * Returns a list of all bnodes occurring in a list of statements
184
- * @private
185
- */
186
- statementArrayBnodes(sts) {
187
- var bnodes = [];
188
- for (let i = 0; i < sts.length; i++) {
189
- bnodes = bnodes.concat(this.statementBnodes(sts[i]));
190
- }
191
- bnodes.sort(); // in place sort - result may have duplicates
192
- var bnodes2 = [];
193
- for (let j = 0; j < bnodes.length; j++) {
194
- if (j === 0 || !bnodes[j].equals(bnodes[j - 1])) {
195
- bnodes2.push(bnodes[j]);
196
- }
197
- }
198
- return bnodes2;
199
- }
199
+ /**
200
+ * Returns a list of all bnodes occurring in a statement
201
+ * @private
202
+ */
203
+ }, {
204
+ key: "statementBnodes",
205
+ value: function statementBnodes(st) {
206
+ return [st.subject, st.predicate, st.object].filter(function (x) {
207
+ return isBlankNode(x);
208
+ });
209
+ }
200
210
 
201
- /**
202
- * Makes a cached list of [Inverse-]Functional properties
203
- * @private
204
- */
205
- cacheIfps() {
206
- this.ifps = {};
207
- var a = this.store.each(undefined, this.ns.rdf('type'), this.ns.owl('InverseFunctionalProperty'));
208
- for (let i = 0; i < a.length; i++) {
209
- this.ifps[a[i].value] = true;
211
+ /**
212
+ * Returns a list of all bnodes occurring in a list of statements
213
+ * @private
214
+ */
215
+ }, {
216
+ key: "statementArrayBnodes",
217
+ value: function statementArrayBnodes(sts) {
218
+ var bnodes = [];
219
+ for (var i = 0; i < sts.length; i++) {
220
+ bnodes = bnodes.concat(this.statementBnodes(sts[i]));
221
+ }
222
+ bnodes.sort(); // in place sort - result may have duplicates
223
+ var bnodes2 = [];
224
+ for (var j = 0; j < bnodes.length; j++) {
225
+ if (j === 0 || !bnodes[j].equals(bnodes[j - 1])) {
226
+ bnodes2.push(bnodes[j]);
227
+ }
228
+ }
229
+ return bnodes2;
210
230
  }
211
- this.fps = {};
212
- a = this.store.each(undefined, this.ns.rdf('type'), this.ns.owl('FunctionalProperty'));
213
- for (let i = 0; i < a.length; i++) {
214
- this.fps[a[i].value] = true;
231
+
232
+ /**
233
+ * Makes a cached list of [Inverse-]Functional properties
234
+ * @private
235
+ */
236
+ }, {
237
+ key: "cacheIfps",
238
+ value: function cacheIfps() {
239
+ this.ifps = {};
240
+ var a = this.store.each(undefined, this.ns.rdf('type'), this.ns.owl('InverseFunctionalProperty'));
241
+ for (var i = 0; i < a.length; i++) {
242
+ this.ifps[a[i].value] = true;
243
+ }
244
+ this.fps = {};
245
+ a = this.store.each(undefined, this.ns.rdf('type'), this.ns.owl('FunctionalProperty'));
246
+ for (var _i3 = 0; _i3 < a.length; _i3++) {
247
+ this.fps[a[_i3].value] = true;
248
+ }
215
249
  }
216
- }
217
250
 
218
- /**
219
- * Returns a context to bind a given node, up to a given depth
220
- * @private
221
- */
222
- bnodeContext2(x, source, depth) {
223
- // Return a list of statements which indirectly identify a node
224
- // Depth > 1 if try further indirection.
225
- // Return array of statements (possibly empty), or null if failure
226
- var sts = this.store.statementsMatching(undefined, undefined, x, source); // incoming links
227
- var y;
228
- var res;
229
- for (let i = 0; i < sts.length; i++) {
230
- if (this.fps[sts[i].predicate.value]) {
231
- y = sts[i].subject;
232
- if (!y.isBlank) {
233
- return [sts[i]];
234
- }
235
- if (depth) {
236
- res = this.bnodeContext2(y, source, depth - 1);
237
- if (res) {
238
- return res.concat([sts[i]]);
251
+ /**
252
+ * Returns a context to bind a given node, up to a given depth
253
+ * @private
254
+ */
255
+ }, {
256
+ key: "bnodeContext2",
257
+ value: function bnodeContext2(x, source, depth) {
258
+ // Return a list of statements which indirectly identify a node
259
+ // Depth > 1 if try further indirection.
260
+ // Return array of statements (possibly empty), or null if failure
261
+ var sts = this.store.statementsMatching(undefined, undefined, x, source); // incoming links
262
+ var y;
263
+ var res;
264
+ for (var i = 0; i < sts.length; i++) {
265
+ if (this.fps[sts[i].predicate.value]) {
266
+ y = sts[i].subject;
267
+ if (!y.isBlank) {
268
+ return [sts[i]];
269
+ }
270
+ if (depth) {
271
+ res = this.bnodeContext2(y, source, depth - 1);
272
+ if (res) {
273
+ return res.concat([sts[i]]);
274
+ }
239
275
  }
240
276
  }
241
277
  }
242
- }
243
- // outgoing links
244
- sts = this.store.statementsMatching(x, undefined, undefined, source);
245
- for (let i = 0; i < sts.length; i++) {
246
- if (this.ifps[sts[i].predicate.value]) {
247
- y = sts[i].object;
248
- if (!y.isBlank) {
249
- return [sts[i]];
250
- }
251
- if (depth) {
252
- res = this.bnodeContext2(y, source, depth - 1);
253
- if (res) {
254
- return res.concat([sts[i]]);
278
+ // outgoing links
279
+ sts = this.store.statementsMatching(x, undefined, undefined, source);
280
+ for (var _i4 = 0; _i4 < sts.length; _i4++) {
281
+ if (this.ifps[sts[_i4].predicate.value]) {
282
+ y = sts[_i4].object;
283
+ if (!y.isBlank) {
284
+ return [sts[_i4]];
285
+ }
286
+ if (depth) {
287
+ res = this.bnodeContext2(y, source, depth - 1);
288
+ if (res) {
289
+ return res.concat([sts[_i4]]);
290
+ }
255
291
  }
256
292
  }
257
293
  }
294
+ return null; // Failure
258
295
  }
259
- return null; // Failure
260
- }
261
296
 
262
- /**
263
- * Returns the smallest context to bind a given single bnode
264
- * @private
265
- */
266
- bnodeContext1(x, source) {
267
- // Return a list of statements which indirectly identify a node
268
- // Breadth-first
269
- for (var depth = 0; depth < 3; depth++) {
270
- // Try simple first
271
- var con = this.bnodeContext2(x, source, depth);
272
- if (con !== null) return con;
273
- }
274
- // If we can't guarantee unique with logic just send all info about node
275
- return this.store.connectedStatements(x, source); // was:
276
- // throw new Error('Unable to uniquely identify bnode: ' + x.toNT())
277
- }
297
+ /**
298
+ * Returns the smallest context to bind a given single bnode
299
+ * @private
300
+ */
301
+ }, {
302
+ key: "bnodeContext1",
303
+ value: function bnodeContext1(x, source) {
304
+ // Return a list of statements which indirectly identify a node
305
+ // Breadth-first
306
+ for (var depth = 0; depth < 3; depth++) {
307
+ // Try simple first
308
+ var con = this.bnodeContext2(x, source, depth);
309
+ if (con !== null) return con;
310
+ }
311
+ // If we can't guarantee unique with logic just send all info about node
312
+ return this.store.connectedStatements(x, source); // was:
313
+ // throw new Error('Unable to uniquely identify bnode: ' + x.toNT())
314
+ }
278
315
 
279
- /**
280
- * @private
281
- */
282
- mentioned(x) {
283
- return this.store.statementsMatching(x, null, null, null).length !== 0 ||
284
- // Don't pin fresh bnodes
285
- this.store.statementsMatching(null, x).length !== 0 || this.store.statementsMatching(null, null, x).length !== 0;
286
- }
316
+ /**
317
+ * @private
318
+ */
319
+ }, {
320
+ key: "mentioned",
321
+ value: function mentioned(x) {
322
+ return this.store.statementsMatching(x, null, null, null).length !== 0 ||
323
+ // Don't pin fresh bnodes
324
+ this.store.statementsMatching(null, x).length !== 0 || this.store.statementsMatching(null, null, x).length !== 0;
325
+ }
287
326
 
288
- /**
289
- * @private
290
- */
291
- bnodeContext(bnodes, doc) {
292
- var context = [];
293
- if (bnodes.length) {
294
- this.cacheIfps();
295
- for (let i = 0; i < bnodes.length; i++) {
296
- // Does this occur in old graph?
297
- var bnode = bnodes[i];
298
- if (!this.mentioned(bnode)) continue;
299
- context = context.concat(this.bnodeContext1(bnode, doc));
300
- }
301
- }
302
- return context;
303
- }
327
+ /**
328
+ * @private
329
+ */
330
+ }, {
331
+ key: "bnodeContext",
332
+ value: function bnodeContext(bnodes, doc) {
333
+ var context = [];
334
+ if (bnodes.length) {
335
+ this.cacheIfps();
336
+ for (var i = 0; i < bnodes.length; i++) {
337
+ // Does this occur in old graph?
338
+ var bnode = bnodes[i];
339
+ if (!this.mentioned(bnode)) continue;
340
+ context = context.concat(this.bnodeContext1(bnode, doc));
341
+ }
342
+ }
343
+ return context;
344
+ }
304
345
 
305
- /**
306
- * Returns the best context for a single statement
307
- * @private
308
- */
309
- statementContext(st) {
310
- var bnodes = this.statementBnodes(st);
311
- return this.bnodeContext(bnodes, st.graph);
312
- }
346
+ /**
347
+ * Returns the best context for a single statement
348
+ * @private
349
+ */
350
+ }, {
351
+ key: "statementContext",
352
+ value: function statementContext(st) {
353
+ var bnodes = this.statementBnodes(st);
354
+ return this.bnodeContext(bnodes, st.graph);
355
+ }
313
356
 
314
- /**
315
- * @private
316
- */
317
- contextWhere(context) {
318
- var updater = this;
319
- return !context || context.length === 0 ? '' : 'WHERE { ' + context.map(function (x) {
320
- return updater.anonymizeNT(x);
321
- }).join('\n') + ' }\n';
322
- }
357
+ /**
358
+ * @private
359
+ */
360
+ }, {
361
+ key: "contextWhere",
362
+ value: function contextWhere(context) {
363
+ var updater = this;
364
+ return !context || context.length === 0 ? '' : 'WHERE { ' + context.map(function (x) {
365
+ return updater.anonymizeNT(x);
366
+ }).join('\n') + ' }\n';
367
+ }
323
368
 
324
- /**
325
- * @private
326
- */
327
- fire(uri, query, callbackFunction) {
328
- let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
329
- return Promise.resolve().then(() => {
330
- if (!uri) {
331
- throw new Error('No URI given for remote editing operation: ' + query);
332
- }
333
- // console.log('UpdateManager: sending update to <' + uri + '>')
369
+ /**
370
+ * @private
371
+ */
372
+ }, {
373
+ key: "fire",
374
+ value: function fire(uri, query, callbackFunction) {
375
+ var _this = this;
376
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
377
+ return Promise.resolve().then(function () {
378
+ if (!uri) {
379
+ throw new Error('No URI given for remote editing operation: ' + query);
380
+ }
381
+ // console.log('UpdateManager: sending update to <' + uri + '>')
334
382
 
335
- options.noMeta = true;
336
- options.contentType = 'application/sparql-update';
337
- options.body = query;
338
- return this.store.fetcher.webOperation('PATCH', uri, options);
339
- }).then(response => {
340
- if (!response.ok) {
341
- let message = 'UpdateManager: update failed for <' + uri + '> status=' + response.status + ', ' + response.statusText + '\n for query: ' + query;
342
- // console.log(message)
343
- throw new Error(message);
344
- }
345
-
346
- // console.log('UpdateManager: update Ok for <' + uri + '>')
347
-
348
- callbackFunction(uri, response.ok, response.responseText, response);
349
- }).catch(err => {
350
- callbackFunction(uri, false, err.message, err);
351
- });
352
- }
383
+ options.noMeta = true;
384
+ options.contentType = 'application/sparql-update';
385
+ options.body = query;
386
+ return _this.store.fetcher.webOperation('PATCH', uri, options);
387
+ }).then(function (response) {
388
+ if (!response.ok) {
389
+ var _message = 'UpdateManager: update failed for <' + uri + '> status=' + response.status + ', ' + response.statusText + '\n for query: ' + query;
390
+ // console.log(message)
391
+ throw new Error(_message);
392
+ }
353
393
 
354
- // ARE THESE THEE FUNCTIONS USED? DEPROCATE?
355
-
356
- /** return a statemnet updating function
357
- *
358
- * This does NOT update the statement.
359
- * It returns an object which includes
360
- * function which can be used to change the object of the statement.
361
- */
362
- update_statement(statement) {
363
- if (statement && !statement.graph) {
364
- return;
365
- }
366
- var updater = this;
367
- var context = this.statementContext(statement);
368
- return {
369
- statement: statement ? [statement.subject, statement.predicate, statement.object, statement.graph] : undefined,
370
- statementNT: statement ? this.anonymizeNT(statement) : undefined,
371
- where: updater.contextWhere(context),
372
- set_object: function (obj, callbackFunction) {
373
- var query = this.where;
374
- query += 'DELETE DATA { ' + this.statementNT + ' } ;\n';
375
- query += 'INSERT DATA { ' +
376
- // @ts-ignore `this` might refer to the wrong scope. Does this work?
377
- this.anonymize(this.statement[0]) + ' ' +
378
- // @ts-ignore
379
- this.anonymize(this.statement[1]) + ' ' +
380
- // @ts-ignore
381
- this.anonymize(obj) + ' ' + ' . }\n';
382
- updater.fire(this.statement[3].value, query, callbackFunction);
383
- }
384
- };
385
- }
386
- insert_statement(st, callbackFunction) {
387
- var st0 = st instanceof Array ? st[0] : st;
388
- var query = this.contextWhere(this.statementContext(st0));
389
- if (st instanceof Array) {
390
- var stText = '';
391
- for (let i = 0; i < st.length; i++) stText += st[i] + '\n';
392
- query += 'INSERT DATA { ' + stText + ' }\n';
393
- } else {
394
- query += 'INSERT DATA { ' + this.anonymize(st.subject) + ' ' + this.anonymize(st.predicate) + ' ' + this.anonymize(st.object) + ' ' + ' . }\n';
395
- }
396
- this.fire(st0.graph.value, query, callbackFunction);
397
- }
398
- delete_statement(st, callbackFunction) {
399
- var st0 = st instanceof Array ? st[0] : st;
400
- var query = this.contextWhere(this.statementContext(st0));
401
- if (st instanceof Array) {
402
- var stText = '';
403
- for (let i = 0; i < st.length; i++) stText += st[i] + '\n';
404
- query += 'DELETE DATA { ' + stText + ' }\n';
405
- } else {
406
- query += 'DELETE DATA { ' + this.anonymize(st.subject) + ' ' + this.anonymize(st.predicate) + ' ' + this.anonymize(st.object) + ' ' + ' . }\n';
407
- }
408
- this.fire(st0.graph.value, query, callbackFunction);
409
- }
394
+ // console.log('UpdateManager: update Ok for <' + uri + '>')
410
395
 
411
- /// //////////////////////
396
+ callbackFunction(uri, response.ok, response.responseText, response);
397
+ }).catch(function (err) {
398
+ callbackFunction(uri, false, err.message, err);
399
+ });
400
+ }
412
401
 
413
- /**
414
- * Requests a now or future action to refresh changes coming downstream
415
- * This is designed to allow the system to re-request the server version,
416
- * when a websocket has pinged to say there are changes.
417
- * If the websocket, by contrast, has sent a patch, then this may not be necessary.
418
- *
419
- * @param doc
420
- * @param action
421
- */
422
- requestDownstreamAction(doc, action) {
423
- var control = this.patchControlFor(doc);
424
- if (!control.pendingUpstream) {
425
- action(doc);
426
- } else {
427
- if (control.downstreamAction) {
428
- if ('' + control.downstreamAction !== '' + action) {
429
- // Kludge compare
430
- throw new Error("Can't wait for > 1 different downstream actions");
402
+ // ARE THESE THEE FUNCTIONS USED? DEPROCATE?
403
+
404
+ /** return a statemnet updating function
405
+ *
406
+ * This does NOT update the statement.
407
+ * It returns an object which includes
408
+ * function which can be used to change the object of the statement.
409
+ */
410
+ }, {
411
+ key: "update_statement",
412
+ value: function update_statement(statement) {
413
+ if (statement && !statement.graph) {
414
+ return;
415
+ }
416
+ var updater = this;
417
+ var context = this.statementContext(statement);
418
+ return {
419
+ statement: statement ? [statement.subject, statement.predicate, statement.object, statement.graph] : undefined,
420
+ statementNT: statement ? this.anonymizeNT(statement) : undefined,
421
+ where: updater.contextWhere(context),
422
+ set_object: function set_object(obj, callbackFunction) {
423
+ var query = this.where;
424
+ query += 'DELETE DATA { ' + this.statementNT + ' } ;\n';
425
+ query += 'INSERT DATA { ' +
426
+ // @ts-ignore `this` might refer to the wrong scope. Does this work?
427
+ this.anonymize(this.statement[0]) + ' ' +
428
+ // @ts-ignore
429
+ this.anonymize(this.statement[1]) + ' ' +
430
+ // @ts-ignore
431
+ this.anonymize(obj) + ' ' + ' . }\n';
432
+ updater.fire(this.statement[3].value, query, callbackFunction);
431
433
  }
434
+ };
435
+ }
436
+ }, {
437
+ key: "insert_statement",
438
+ value: function insert_statement(st, callbackFunction) {
439
+ var st0 = st instanceof Array ? st[0] : st;
440
+ var query = this.contextWhere(this.statementContext(st0));
441
+ if (st instanceof Array) {
442
+ var stText = '';
443
+ for (var i = 0; i < st.length; i++) stText += st[i] + '\n';
444
+ query += 'INSERT DATA { ' + stText + ' }\n';
432
445
  } else {
433
- control.downstreamAction = action;
446
+ query += 'INSERT DATA { ' + this.anonymize(st.subject) + ' ' + this.anonymize(st.predicate) + ' ' + this.anonymize(st.object) + ' ' + ' . }\n';
434
447
  }
448
+ this.fire(st0.graph.value, query, callbackFunction);
449
+ }
450
+ }, {
451
+ key: "delete_statement",
452
+ value: function delete_statement(st, callbackFunction) {
453
+ var st0 = st instanceof Array ? st[0] : st;
454
+ var query = this.contextWhere(this.statementContext(st0));
455
+ if (st instanceof Array) {
456
+ var stText = '';
457
+ for (var i = 0; i < st.length; i++) stText += st[i] + '\n';
458
+ query += 'DELETE DATA { ' + stText + ' }\n';
459
+ } else {
460
+ query += 'DELETE DATA { ' + this.anonymize(st.subject) + ' ' + this.anonymize(st.predicate) + ' ' + this.anonymize(st.object) + ' ' + ' . }\n';
461
+ }
462
+ this.fire(st0.graph.value, query, callbackFunction);
435
463
  }
436
- }
437
464
 
438
- /**
439
- * We want to start counting websocket notifications
440
- * to distinguish the ones from others from our own.
441
- */
442
- clearUpstreamCount(doc) {
443
- var control = this.patchControlFor(doc);
444
- control.upstreamCount = 0;
445
- }
446
- getUpdatesVia(doc) {
447
- var linkHeaders = this.store.fetcher.getHeader(doc, 'updates-via');
448
- if (!linkHeaders || !linkHeaders.length) return null;
449
- return linkHeaders[0].trim();
450
- }
451
- addDownstreamChangeListener(doc, listener) {
452
- var control = this.patchControlFor(doc);
453
- if (!control.downstreamChangeListeners) {
454
- control.downstreamChangeListeners = [];
455
- }
456
- control.downstreamChangeListeners.push(listener);
457
- this.setRefreshHandler(doc, doc => {
458
- this.reloadAndSync(doc);
459
- });
460
- }
461
- reloadAndSync(doc) {
462
- var control = this.patchControlFor(doc);
463
- var updater = this;
464
- if (control.reloading) {
465
- // console.log(' Already reloading - note this load may be out of date')
466
- control.outOfDate = true;
467
- return; // once only needed @@ Not true, has changed again
468
- }
469
-
470
- control.reloading = true;
471
- var retryTimeout = 1000; // ms
472
- var tryReload = function () {
473
- // console.log('try reload - timeout = ' + retryTimeout)
474
- updater.reload(updater.store, doc, function (ok, message, response) {
475
- if (ok) {
476
- if (control.downstreamChangeListeners) {
477
- for (let i = 0; i < control.downstreamChangeListeners.length; i++) {
478
- // console.log(' Calling downstream listener ' + i)
479
- control.downstreamChangeListeners[i]();
480
- }
481
- }
482
- control.reloading = false;
483
- if (control.outOfDate) {
484
- // console.log(' Extra reload because of extra update.')
485
- control.outOfDate = false;
486
- tryReload();
465
+ /// //////////////////////
466
+
467
+ /**
468
+ * Requests a now or future action to refresh changes coming downstream
469
+ * This is designed to allow the system to re-request the server version,
470
+ * when a websocket has pinged to say there are changes.
471
+ * If the websocket, by contrast, has sent a patch, then this may not be necessary.
472
+ *
473
+ * @param doc
474
+ * @param action
475
+ */
476
+ }, {
477
+ key: "requestDownstreamAction",
478
+ value: function requestDownstreamAction(doc, action) {
479
+ var control = this.patchControlFor(doc);
480
+ if (!control.pendingUpstream) {
481
+ action(doc);
482
+ } else {
483
+ if (control.downstreamAction) {
484
+ if ('' + control.downstreamAction !== '' + action) {
485
+ // Kludge compare
486
+ throw new Error("Can't wait for > 1 different downstream actions");
487
487
  }
488
488
  } else {
489
- control.reloading = false;
490
- if (response.status === 0) {
491
- // console.log('Network error refreshing the data. Retrying in ' +
492
- // retryTimeout / 1000)
493
- control.reloading = true;
494
- retryTimeout = retryTimeout * 2;
495
- setTimeout(tryReload, retryTimeout);
496
- } else {
497
- // console.log('Error ' + (response as Response).status + 'refreshing the data:' +
498
- // message + '. Stopped' + doc)
499
- }
489
+ control.downstreamAction = action;
500
490
  }
501
- });
502
- };
503
- tryReload();
504
- }
505
-
506
- /**
507
- * Sets up websocket to listen on
508
- *
509
- * There is coordination between upstream changes and downstream ones
510
- * so that a reload is not done in the middle of an upstream patch.
511
- * If you use this API then you get called when a change happens, and you
512
- * have to reload the file yourself, and then refresh the UI.
513
- * Alternative is addDownstreamChangeListener(), where you do not
514
- * have to do the reload yourself. Do mot mix them.
515
- *
516
- * kb contains the HTTP metadata from previous operations
517
- *
518
- * @param doc
519
- * @param handler
520
- *
521
- * @returns {boolean}
522
- */
523
- setRefreshHandler(doc, handler) {
524
- let wssURI = this.getUpdatesVia(doc); // relative
525
- // var kb = this.store
526
- var theHandler = handler;
527
- var self = this;
528
- var updater = this;
529
- var retryTimeout = 1500; // *2 will be 3 Seconds, 6, 12, etc
530
- var retries = 0;
531
- if (!wssURI) {
532
- // console.log('Server does not support live updates through Updates-Via :-(')
533
- return false;
534
- }
535
- wssURI = uriJoin(wssURI, doc.value);
536
- const validWssURI = wssURI.replace(/^http:/, 'ws:').replace(/^https:/, 'wss:');
537
- // console.log('Web socket URI ' + wssURI)
538
-
539
- var openWebsocket = function () {
540
- // From https://github.com/solid/solid-spec#live-updates
541
- var socket;
542
- if (typeof WebSocket !== 'undefined') {
543
- socket = new WebSocket(validWssURI);
544
- } else if (typeof window !== 'undefined' && window.WebSocket) {
545
- socket = window.WebSocket(validWssURI);
546
- } else {
547
- // console.log('Live update disabled, as WebSocket not supported by platform :-(')
548
- return;
549
491
  }
550
- socket.onopen = function () {
551
- // console.log(' websocket open')
552
- retryTimeout = 1500; // reset timeout to fast on success
553
- this.send('sub ' + doc.value);
554
- if (retries) {
555
- // console.log('Web socket has been down, better check for any news.')
556
- updater.requestDownstreamAction(doc, theHandler);
557
- }
558
- };
559
- var control = self.patchControlFor(doc);
492
+ }
493
+
494
+ /**
495
+ * We want to start counting websocket notifications
496
+ * to distinguish the ones from others from our own.
497
+ */
498
+ }, {
499
+ key: "clearUpstreamCount",
500
+ value: function clearUpstreamCount(doc) {
501
+ var control = this.patchControlFor(doc);
560
502
  control.upstreamCount = 0;
561
- socket.onerror = function onerror(err) {
562
- // console.log('Error on Websocket:', err)
563
- };
503
+ }
504
+ }, {
505
+ key: "getUpdatesVia",
506
+ value: function getUpdatesVia(doc) {
507
+ var linkHeaders = this.store.fetcher.getHeader(doc, 'updates-via');
508
+ if (!linkHeaders || !linkHeaders.length) return null;
509
+ return linkHeaders[0].trim();
510
+ }
511
+ }, {
512
+ key: "addDownstreamChangeListener",
513
+ value: function addDownstreamChangeListener(doc, listener) {
514
+ var _this2 = this;
515
+ var control = this.patchControlFor(doc);
516
+ if (!control.downstreamChangeListeners) {
517
+ control.downstreamChangeListeners = [];
518
+ }
519
+ control.downstreamChangeListeners.push(listener);
520
+ this.setRefreshHandler(doc, function (doc) {
521
+ _this2.reloadAndSync(doc);
522
+ });
523
+ }
524
+ }, {
525
+ key: "reloadAndSync",
526
+ value: function reloadAndSync(doc) {
527
+ var control = this.patchControlFor(doc);
528
+ var updater = this;
529
+ if (control.reloading) {
530
+ // console.log(' Already reloading - note this load may be out of date')
531
+ control.outOfDate = true;
532
+ return; // once only needed @@ Not true, has changed again
533
+ }
564
534
 
565
- // https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
566
- //
567
- // 1000 CLOSE_NORMAL Normal closure; the connection successfully completed whatever purpose for which it was created.
568
- // 1001 CLOSE_GOING_AWAY The endpoint is going away, either
569
- // because of a server failure or because the browser is navigating away from the page that opened the connection.
570
- // 1002 CLOSE_PROTOCOL_ERROR The endpoint is terminating the connection due to a protocol error.
571
- // 1003 CLOSE_UNSUPPORTED The connection is being terminated because the endpoint
572
- // received data of a type it cannot accept (for example, a text-only endpoint received binary data).
573
- // 1004 Reserved. A meaning might be defined in the future.
574
- // 1005 CLOSE_NO_STATUS Reserved. Indicates that no status code was provided even though one was expected.
575
- // 1006 CLOSE_ABNORMAL Reserved. Used to indicate that a connection was closed abnormally (
576
- //
577
- //
578
- socket.onclose = function (event) {
579
- // console.log('*** Websocket closed with code ' + event.code +
580
- // ", reason '" + event.reason + "' clean = " + event.wasClean)
581
- retryTimeout *= 2;
582
- retries += 1;
583
- // console.log('Retrying in ' + retryTimeout + 'ms') // (ask user?)
584
- setTimeout(function () {
585
- // console.log('Trying websocket again')
586
- openWebsocket();
587
- }, retryTimeout);
588
- };
589
- socket.onmessage = function (msg) {
590
- if (msg.data && msg.data.slice(0, 3) === 'pub') {
591
- if ('upstreamCount' in control) {
592
- control.upstreamCount -= 1;
593
- if (control.upstreamCount >= 0) {
594
- // console.log('just an echo: ' + control.upstreamCount)
595
- return; // Just an echo
535
+ control.reloading = true;
536
+ var retryTimeout = 1000; // ms
537
+ var tryReload = function tryReload() {
538
+ // console.log('try reload - timeout = ' + retryTimeout)
539
+ updater.reload(updater.store, doc, function (ok, message, response) {
540
+ if (ok) {
541
+ if (control.downstreamChangeListeners) {
542
+ for (var i = 0; i < control.downstreamChangeListeners.length; i++) {
543
+ // console.log(' Calling downstream listener ' + i)
544
+ control.downstreamChangeListeners[i]();
545
+ }
546
+ }
547
+ control.reloading = false;
548
+ if (control.outOfDate) {
549
+ // console.log(' Extra reload because of extra update.')
550
+ control.outOfDate = false;
551
+ tryReload();
552
+ }
553
+ } else {
554
+ control.reloading = false;
555
+ if (response.status === 0) {
556
+ // console.log('Network error refreshing the data. Retrying in ' +
557
+ // retryTimeout / 1000)
558
+ control.reloading = true;
559
+ retryTimeout = retryTimeout * 2;
560
+ setTimeout(tryReload, retryTimeout);
561
+ } else {
562
+ // console.log('Error ' + (response as Response).status + 'refreshing the data:' +
563
+ // message + '. Stopped' + doc)
596
564
  }
597
565
  }
598
- // console.log('Assume a real downstream change: ' + control.upstreamCount + ' -> 0')
599
- control.upstreamCount = 0;
600
- self.requestDownstreamAction(doc, theHandler);
601
- }
566
+ });
602
567
  };
603
- }; // openWebsocket
604
- openWebsocket();
605
- return true;
606
- }
568
+ tryReload();
569
+ }
607
570
 
608
- /**
609
- * This high-level function updates the local store iff the web is changed successfully.
610
- * Deletions, insertions may be undefined or single statements or lists or formulae (may contain bnodes which can be indirectly identified by a where clause).
611
- * The `why` property of each statement must be the give the web document to be updated.
612
- * The statements to be deleted and inserted may span more than one web document.
613
- * @param deletions - Statement or statements to be deleted.
614
- * @param insertions - Statement or statements to be inserted.
615
- * @returns a promise
616
- */
617
- updateMany(deletions) {
618
- let insertions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
619
- const docs = deletions.concat(insertions).map(st => st.why);
620
- const thisUpdater = this;
621
- const uniqueDocs = [];
622
- docs.forEach(doc => {
623
- if (!uniqueDocs.find(uniqueDoc => uniqueDoc.equals(doc))) uniqueDocs.push(doc);
624
- });
625
- const updates = uniqueDocs.map(doc => thisUpdater.update(deletions.filter(st => st.why.equals(doc)), insertions.filter(st => st.why.equals(doc))));
626
- if (updates.length > 1) {
627
- // console.log(`@@ updateMany to ${updates.length}: ${uniqueDocs}`)
628
- }
629
- return Promise.all(updates);
630
- }
571
+ /**
572
+ * Sets up websocket to listen on
573
+ *
574
+ * There is coordination between upstream changes and downstream ones
575
+ * so that a reload is not done in the middle of an upstream patch.
576
+ * If you use this API then you get called when a change happens, and you
577
+ * have to reload the file yourself, and then refresh the UI.
578
+ * Alternative is addDownstreamChangeListener(), where you do not
579
+ * have to do the reload yourself. Do mot mix them.
580
+ *
581
+ * kb contains the HTTP metadata from previous operations
582
+ *
583
+ * @param doc
584
+ * @param handler
585
+ *
586
+ * @returns {boolean}
587
+ */
588
+ }, {
589
+ key: "setRefreshHandler",
590
+ value: function setRefreshHandler(doc, handler) {
591
+ var wssURI = this.getUpdatesVia(doc); // relative
592
+ // var kb = this.store
593
+ var theHandler = handler;
594
+ var self = this;
595
+ var updater = this;
596
+ var retryTimeout = 1500; // *2 will be 3 Seconds, 6, 12, etc
597
+ var retries = 0;
598
+ if (!wssURI) {
599
+ // console.log('Server does not support live updates through Updates-Via :-(')
600
+ return false;
601
+ }
602
+ wssURI = uriJoin(wssURI, doc.value);
603
+ var validWssURI = wssURI.replace(/^http:/, 'ws:').replace(/^https:/, 'wss:');
604
+ // console.log('Web socket URI ' + wssURI)
631
605
 
632
- /**
633
- * This high-level function updates the local store iff the web is changed successfully.
634
- * Deletions, insertions may be undefined or single statements or lists or formulae (may contain bnodes which can be indirectly identified by a where clause).
635
- * The `why` property of each statement must be the same and give the web document to be updated.
636
- * @param deletions - Statement or statements to be deleted.
637
- * @param insertions - Statement or statements to be inserted.
638
- * @param callback - called as callbackFunction(uri, success, errorbody)
639
- * OR returns a promise
640
- * @param options - Options for the fetch call
641
- */
642
- update(deletions, insertions, callback, secondTry) {
643
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
644
- if (!callback) {
645
- var thisUpdater = this;
646
- return new Promise(function (resolve, reject) {
647
- // Promise version
648
- thisUpdater.update(deletions, insertions, function (uri, ok, errorBody) {
649
- if (!ok) {
650
- reject(new Error(errorBody));
651
- } else {
652
- resolve();
606
+ var openWebsocket = function openWebsocket() {
607
+ // From https://github.com/solid/solid-spec#live-updates
608
+ var socket;
609
+ if (typeof WebSocket !== 'undefined') {
610
+ socket = new WebSocket(validWssURI);
611
+ } else if (typeof window !== 'undefined' && window.WebSocket) {
612
+ socket = window.WebSocket(validWssURI);
613
+ } else {
614
+ // console.log('Live update disabled, as WebSocket not supported by platform :-(')
615
+ return;
616
+ }
617
+ socket.onopen = function () {
618
+ // console.log(' websocket open')
619
+ retryTimeout = 1500; // reset timeout to fast on success
620
+ this.send('sub ' + doc.value);
621
+ if (retries) {
622
+ // console.log('Web socket has been down, better check for any news.')
623
+ updater.requestDownstreamAction(doc, theHandler);
653
624
  }
654
- }, secondTry, options); // callbackFunction
655
- }); // promise
656
- } // if
625
+ };
626
+ var control = self.patchControlFor(doc);
627
+ control.upstreamCount = 0;
628
+ socket.onerror = function onerror(err) {
629
+ // console.log('Error on Websocket:', err)
630
+ };
657
631
 
658
- try {
659
- var kb = this.store;
660
- var ds = !deletions ? [] : isStore(deletions) ? deletions.statements : deletions instanceof Array ? deletions : [deletions];
661
- var is = !insertions ? [] : isStore(insertions) ? insertions.statements : insertions instanceof Array ? insertions : [insertions];
662
- if (!(ds instanceof Array)) {
663
- throw new Error('Type Error ' + typeof ds + ': ' + ds);
664
- }
665
- if (!(is instanceof Array)) {
666
- throw new Error('Type Error ' + typeof is + ': ' + is);
667
- }
668
- if (ds.length === 0 && is.length === 0) {
669
- return callback(null, true); // success -- nothing needed to be done.
670
- }
632
+ // https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
633
+ //
634
+ // 1000 CLOSE_NORMAL Normal closure; the connection successfully completed whatever purpose for which it was created.
635
+ // 1001 CLOSE_GOING_AWAY The endpoint is going away, either
636
+ // because of a server failure or because the browser is navigating away from the page that opened the connection.
637
+ // 1002 CLOSE_PROTOCOL_ERROR The endpoint is terminating the connection due to a protocol error.
638
+ // 1003 CLOSE_UNSUPPORTED The connection is being terminated because the endpoint
639
+ // received data of a type it cannot accept (for example, a text-only endpoint received binary data).
640
+ // 1004 Reserved. A meaning might be defined in the future.
641
+ // 1005 CLOSE_NO_STATUS Reserved. Indicates that no status code was provided even though one was expected.
642
+ // 1006 CLOSE_ABNORMAL Reserved. Used to indicate that a connection was closed abnormally (
643
+ //
644
+ //
645
+ socket.onclose = function (event) {
646
+ // console.log('*** Websocket closed with code ' + event.code +
647
+ // ", reason '" + event.reason + "' clean = " + event.wasClean)
648
+ retryTimeout *= 2;
649
+ retries += 1;
650
+ // console.log('Retrying in ' + retryTimeout + 'ms') // (ask user?)
651
+ setTimeout(function () {
652
+ // console.log('Trying websocket again')
653
+ openWebsocket();
654
+ }, retryTimeout);
655
+ };
656
+ socket.onmessage = function (msg) {
657
+ if (msg.data && msg.data.slice(0, 3) === 'pub') {
658
+ if ('upstreamCount' in control) {
659
+ control.upstreamCount -= 1;
660
+ if (control.upstreamCount >= 0) {
661
+ // console.log('just an echo: ' + control.upstreamCount)
662
+ return; // Just an echo
663
+ }
664
+ }
665
+ // console.log('Assume a real downstream change: ' + control.upstreamCount + ' -> 0')
666
+ control.upstreamCount = 0;
667
+ self.requestDownstreamAction(doc, theHandler);
668
+ }
669
+ };
670
+ }; // openWebsocket
671
+ openWebsocket();
672
+ return true;
673
+ }
671
674
 
672
- var doc = ds.length ? ds[0].graph : is[0].graph;
673
- if (!doc) {
674
- let message = 'Error patching: statement does not specify which document to patch:' + ds[0] + ', ' + is[0];
675
- // console.log(message)
676
- throw new Error(message);
675
+ /**
676
+ * This high-level function updates the local store iff the web is changed successfully.
677
+ * Deletions, insertions may be undefined or single statements or lists or formulae (may contain bnodes which can be indirectly identified by a where clause).
678
+ * The `why` property of each statement must be the give the web document to be updated.
679
+ * The statements to be deleted and inserted may span more than one web document.
680
+ * @param deletions - Statement or statements to be deleted.
681
+ * @param insertions - Statement or statements to be inserted.
682
+ * @returns a promise
683
+ */
684
+ }, {
685
+ key: "updateMany",
686
+ value: function updateMany(deletions) {
687
+ var insertions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
688
+ var docs = deletions.concat(insertions).map(function (st) {
689
+ return st.why;
690
+ });
691
+ var thisUpdater = this;
692
+ var uniqueDocs = [];
693
+ docs.forEach(function (doc) {
694
+ if (!uniqueDocs.find(function (uniqueDoc) {
695
+ return uniqueDoc.equals(doc);
696
+ })) uniqueDocs.push(doc);
697
+ });
698
+ var updates = uniqueDocs.map(function (doc) {
699
+ return thisUpdater.update(deletions.filter(function (st) {
700
+ return st.why.equals(doc);
701
+ }), insertions.filter(function (st) {
702
+ return st.why.equals(doc);
703
+ }));
704
+ });
705
+ if (updates.length > 1) {
706
+ // console.log(`@@ updateMany to ${updates.length}: ${uniqueDocs}`)
677
707
  }
678
- var control = this.patchControlFor(doc);
679
- var startTime = Date.now();
680
- var props = ['subject', 'predicate', 'object', 'why'];
681
- var verbs = ['insert', 'delete'];
682
- var clauses = {
683
- 'delete': ds,
684
- 'insert': is
685
- };
686
- verbs.map(function (verb) {
687
- clauses[verb].map(function (st) {
688
- if (!doc.equals(st.graph)) {
689
- throw new Error('update: destination ' + doc + ' inconsistent with delete quad ' + st.graph);
690
- }
691
- props.map(function (prop) {
692
- if (typeof st[prop] === 'undefined') {
693
- throw new Error('update: undefined ' + prop + ' of statement.');
708
+ return Promise.all(updates);
709
+ }
710
+
711
+ /**
712
+ * This high-level function updates the local store iff the web is changed successfully.
713
+ * Deletions, insertions may be undefined or single statements or lists or formulae (may contain bnodes which can be indirectly identified by a where clause).
714
+ * The `why` property of each statement must be the same and give the web document to be updated.
715
+ * @param deletions - Statement or statements to be deleted.
716
+ * @param insertions - Statement or statements to be inserted.
717
+ * @param callback - called as callbackFunction(uri, success, errorbody)
718
+ * OR returns a promise
719
+ * @param options - Options for the fetch call
720
+ */
721
+ }, {
722
+ key: "update",
723
+ value: function update(deletions, insertions, callback, secondTry) {
724
+ var _this3 = this;
725
+ var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
726
+ if (!callback) {
727
+ var thisUpdater = this;
728
+ return new Promise(function (resolve, reject) {
729
+ // Promise version
730
+ thisUpdater.update(deletions, insertions, function (uri, ok, errorBody) {
731
+ if (!ok) {
732
+ reject(new Error(errorBody));
733
+ } else {
734
+ resolve();
735
+ }
736
+ }, secondTry, options); // callbackFunction
737
+ }); // promise
738
+ } // if
739
+
740
+ try {
741
+ var kb = this.store;
742
+ var ds = !deletions ? [] : isStore(deletions) ? deletions.statements : deletions instanceof Array ? deletions : [deletions];
743
+ var is = !insertions ? [] : isStore(insertions) ? insertions.statements : insertions instanceof Array ? insertions : [insertions];
744
+ if (!(ds instanceof Array)) {
745
+ throw new Error('Type Error ' + _typeof(ds) + ': ' + ds);
746
+ }
747
+ if (!(is instanceof Array)) {
748
+ throw new Error('Type Error ' + _typeof(is) + ': ' + is);
749
+ }
750
+ if (ds.length === 0 && is.length === 0) {
751
+ return callback(null, true); // success -- nothing needed to be done.
752
+ }
753
+
754
+ var doc = ds.length ? ds[0].graph : is[0].graph;
755
+ if (!doc) {
756
+ var _message2 = 'Error patching: statement does not specify which document to patch:' + ds[0] + ', ' + is[0];
757
+ // console.log(message)
758
+ throw new Error(_message2);
759
+ }
760
+ if (doc.termType !== 'NamedNode') {
761
+ var _message3 = 'Error patching: document not a NamedNode:' + ds[0] + ', ' + is[0];
762
+ // console.log(message)
763
+ throw new Error(_message3);
764
+ }
765
+ var control = this.patchControlFor(doc);
766
+ var startTime = Date.now();
767
+ var props = ['subject', 'predicate', 'object', 'why'];
768
+ var verbs = ['insert', 'delete'];
769
+ var clauses = {
770
+ 'delete': ds,
771
+ 'insert': is
772
+ };
773
+ verbs.map(function (verb) {
774
+ clauses[verb].map(function (st) {
775
+ if (!doc.equals(st.graph)) {
776
+ throw new Error('update: destination ' + doc + ' inconsistent with delete quad ' + st.graph);
694
777
  }
778
+ props.map(function (prop) {
779
+ if (typeof st[prop] === 'undefined') {
780
+ throw new Error('update: undefined ' + prop + ' of statement.');
781
+ }
782
+ });
695
783
  });
696
784
  });
697
- });
698
- var protocol = this.editable(doc.value, kb);
699
- if (protocol === false) {
700
- throw new Error('Update: Can\'t make changes in uneditable ' + doc);
701
- }
702
- if (protocol === undefined) {
703
- // Not enough metadata
704
- if (secondTry) {
705
- throw new Error('Update: Loaded ' + doc + "but stil can't figure out what editing protcol it supports.");
785
+ var protocol = this.editable(doc.value, kb);
786
+ if (protocol === false) {
787
+ throw new Error('Update: Can\'t make changes in uneditable ' + doc);
706
788
  }
707
- // console.log(`Update: have not loaded ${doc} before: loading now...`);
708
- this.store.fetcher.load(doc).then(response => {
709
- this.update(deletions, insertions, callback, true, options);
710
- }, err => {
711
- if (err.response.status === 404) {
712
- // nonexistent files are fine
713
- this.update(deletions, insertions, callback, true, options);
714
- } else {
715
- throw new Error(`Update: Can't get updatability status ${doc} before patching: ${err}`);
789
+ if (protocol === undefined) {
790
+ // Not enough metadata
791
+ if (secondTry) {
792
+ throw new Error('Update: Loaded ' + doc + "but stil can't figure out what editing protcol it supports.");
716
793
  }
717
- });
718
- return;
719
- } else if (protocol.indexOf('SPARQL') >= 0) {
720
- var bnodes = [];
721
- // change ReadOnly type to Mutable type
722
-
723
- if (ds.length) bnodes = this.statementArrayBnodes(ds);
724
- if (is.length) bnodes = bnodes.concat(this.statementArrayBnodes(is));
725
- var context = this.bnodeContext(bnodes, doc);
726
- var whereClause = this.contextWhere(context);
727
- var query = '';
728
- if (whereClause.length) {
729
- // Is there a WHERE clause?
730
- if (ds.length) {
731
- query += 'DELETE { ';
732
- for (let i = 0; i < ds.length; i++) {
733
- query += this.anonymizeNT(ds[i]) + '\n';
794
+ // console.log(`Update: have not loaded ${doc} before: loading now...`);
795
+ this.store.fetcher.load(doc).then(function (response) {
796
+ _this3.update(deletions, insertions, callback, true, options);
797
+ }, function (err) {
798
+ if (err.response.status === 404) {
799
+ // nonexistent files are fine
800
+ _this3.update(deletions, insertions, callback, true, options);
801
+ } else {
802
+ throw new Error("Update: Can't get updatability status ".concat(doc, " before patching: ").concat(err));
734
803
  }
735
- query += ' }\n';
736
- }
737
- if (is.length) {
738
- query += 'INSERT { ';
739
- for (let i = 0; i < is.length; i++) {
740
- query += this.anonymizeNT(is[i]) + '\n';
804
+ });
805
+ return;
806
+ } else if (protocol.indexOf('SPARQL') >= 0) {
807
+ var bnodes = [];
808
+ // change ReadOnly type to Mutable type
809
+
810
+ if (ds.length) bnodes = this.statementArrayBnodes(ds);
811
+ if (is.length) bnodes = bnodes.concat(this.statementArrayBnodes(is));
812
+ var context = this.bnodeContext(bnodes, doc);
813
+ var whereClause = this.contextWhere(context);
814
+ var query = '';
815
+ if (whereClause.length) {
816
+ // Is there a WHERE clause?
817
+ if (ds.length) {
818
+ query += 'DELETE { ';
819
+ for (var i = 0; i < ds.length; i++) {
820
+ query += this.anonymizeNT(ds[i]) + '\n';
821
+ }
822
+ query += ' }\n';
741
823
  }
742
- query += ' }\n';
743
- }
744
- query += whereClause;
745
- } else {
746
- // no where clause
747
- if (ds.length) {
748
- query += 'DELETE DATA { ';
749
- for (let i = 0; i < ds.length; i++) {
750
- query += this.anonymizeNT(ds[i]) + '\n';
824
+ if (is.length) {
825
+ query += 'INSERT { ';
826
+ for (var _i5 = 0; _i5 < is.length; _i5++) {
827
+ query += this.anonymizeNT(is[_i5]) + '\n';
828
+ }
829
+ query += ' }\n';
751
830
  }
752
- query += ' } \n';
753
- }
754
- if (is.length) {
755
- if (ds.length) query += ' ; ';
756
- query += 'INSERT DATA { ';
757
- for (let i = 0; i < is.length; i++) {
758
- query += this.nTriples(is[i]) + '\n';
831
+ query += whereClause;
832
+ } else {
833
+ // no where clause
834
+ if (ds.length) {
835
+ query += 'DELETE DATA { ';
836
+ for (var _i6 = 0; _i6 < ds.length; _i6++) {
837
+ query += this.anonymizeNT(ds[_i6]) + '\n';
838
+ }
839
+ query += ' } \n';
840
+ }
841
+ if (is.length) {
842
+ if (ds.length) query += ' ; ';
843
+ query += 'INSERT DATA { ';
844
+ for (var _i7 = 0; _i7 < is.length; _i7++) {
845
+ query += this.nTriples(is[_i7]) + '\n';
846
+ }
847
+ query += ' }\n';
759
848
  }
760
- query += ' }\n';
761
849
  }
762
- }
763
- // Track pending upstream patches until they have finished their callbackFunction
764
- control.pendingUpstream = control.pendingUpstream ? control.pendingUpstream + 1 : 1;
765
- if ('upstreamCount' in control) {
766
- control.upstreamCount += 1; // count changes we originated ourselves
767
- // console.log('upstream count up to : ' + control.upstreamCount)
768
- }
850
+ // Track pending upstream patches until they have finished their callbackFunction
851
+ control.pendingUpstream = control.pendingUpstream ? control.pendingUpstream + 1 : 1;
852
+ if ('upstreamCount' in control) {
853
+ control.upstreamCount += 1; // count changes we originated ourselves
854
+ // console.log('upstream count up to : ' + control.upstreamCount)
855
+ }
769
856
 
770
- this.fire(doc.value, query, (uri, success, body, response) => {
771
- response.elapsedTimeMs = Date.now() - startTime;
772
- /* console.log(' UpdateManager: Return ' +
773
- (success ? 'success ' : 'FAILURE ') + (response as Response).status +
774
- ' elapsed ' + (response as any).elapsedTimeMs + 'ms')
775
- */
776
- if (success) {
857
+ this.fire(doc.value, query, function (uri, success, body, response) {
858
+ response.elapsedTimeMs = Date.now() - startTime;
859
+ /* console.log(' UpdateManager: Return ' +
860
+ (success ? 'success ' : 'FAILURE ') + (response as Response).status +
861
+ ' elapsed ' + (response as any).elapsedTimeMs + 'ms')
862
+ */
863
+ if (success) {
864
+ try {
865
+ kb.remove(ds);
866
+ } catch (e) {
867
+ success = false;
868
+ body = 'Remote Ok BUT error deleting ' + ds.length + ' from store!!! ' + e;
869
+ } // Add in any case -- help recover from weirdness??
870
+ for (var _i8 = 0; _i8 < is.length; _i8++) {
871
+ kb.add(is[_i8].subject, is[_i8].predicate, is[_i8].object, doc);
872
+ }
873
+ }
874
+ callback(uri, success, body, response);
875
+ control.pendingUpstream -= 1;
876
+ // When upstream patches have been sent, reload state if downstream waiting
877
+ if (control.pendingUpstream === 0 && control.downstreamAction) {
878
+ var downstreamAction = control.downstreamAction;
879
+ delete control.downstreamAction;
880
+ // console.log('delayed downstream action:')
881
+ downstreamAction(doc);
882
+ }
883
+ }, options);
884
+ } else if (protocol.indexOf('DAV') >= 0) {
885
+ this.updateDav(doc, ds, is, callback, options);
886
+ } else {
887
+ if (protocol.indexOf('LOCALFILE') >= 0) {
777
888
  try {
778
- kb.remove(ds);
889
+ this.updateLocalFile(doc, ds, is, callback, options);
779
890
  } catch (e) {
780
- success = false;
781
- body = 'Remote Ok BUT error deleting ' + ds.length + ' from store!!! ' + e;
782
- } // Add in any case -- help recover from weirdness??
783
- for (let i = 0; i < is.length; i++) {
784
- kb.add(is[i].subject, is[i].predicate, is[i].object, doc);
891
+ callback(doc.value, false, 'Exception trying to write back file <' + doc.value + '>\n'
892
+ // + tabulator.Util.stackString(e))
893
+ );
785
894
  }
895
+ } else {
896
+ throw new Error("Unhandled edit method: '" + protocol + "' for " + doc);
786
897
  }
787
- callback(uri, success, body, response);
788
- control.pendingUpstream -= 1;
789
- // When upstream patches have been sent, reload state if downstream waiting
790
- if (control.pendingUpstream === 0 && control.downstreamAction) {
791
- var downstreamAction = control.downstreamAction;
792
- delete control.downstreamAction;
793
- // console.log('delayed downstream action:')
794
- downstreamAction(doc);
795
- }
796
- }, options);
797
- } else if (protocol.indexOf('DAV') >= 0) {
798
- this.updateDav(doc, ds, is, callback, options);
799
- } else {
800
- if (protocol.indexOf('LOCALFILE') >= 0) {
801
- try {
802
- this.updateLocalFile(doc, ds, is, callback, options);
803
- } catch (e) {
804
- callback(doc.value, false, 'Exception trying to write back file <' + doc.value + '>\n'
805
- // + tabulator.Util.stackString(e))
806
- );
807
- }
808
- } else {
809
- throw new Error("Unhandled edit method: '" + protocol + "' for " + doc);
810
898
  }
899
+ } catch (e) {
900
+ callback(undefined, false, 'Exception in update: ' + e + '\n' + Util.stackString(e));
811
901
  }
812
- } catch (e) {
813
- callback(undefined, false, 'Exception in update: ' + e + '\n' + Util.stackString(e));
814
902
  }
815
- }
816
- updateDav(doc, ds, is, callbackFunction) {
817
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
818
- let kb = this.store;
819
- // The code below is derived from Kenny's UpdateCenter.js
820
- var request = kb.any(doc, this.ns.link('request'));
821
- if (!request) {
822
- throw new Error('No record of our HTTP GET request for document: ' + doc);
823
- } // should not happen
824
- var response = kb.any(request, this.ns.link('response'));
825
- if (!response) {
826
- return null; // throw "No record HTTP GET response for document: "+doc
827
- }
828
-
829
- var contentType = kb.the(response, this.ns.httph('content-type')).value;
830
-
831
- // prepare contents of revised document
832
- let newSts = kb.statementsMatching(undefined, undefined, undefined, doc).slice(); // copy!
833
- for (let i = 0; i < ds.length; i++) {
834
- Util.RDFArrayRemove(newSts, ds[i]);
835
- }
836
- for (let i = 0; i < is.length; i++) {
837
- newSts.push(is[i]);
838
- }
839
- const documentString = this.serialize(doc.value, newSts, contentType);
840
-
841
- // Write the new version back
842
- var candidateTarget = kb.the(response, this.ns.httph('content-location'));
843
- var targetURI;
844
- if (candidateTarget) {
845
- targetURI = uriJoin(candidateTarget.value, targetURI);
846
- }
847
- options.contentType = contentType;
848
- options.noMeta = true;
849
- options.body = documentString;
850
- return kb.fetcher.webOperation('PUT', targetURI, options).then(response => {
851
- if (!response.ok) {
852
- throw new Error(response.error);
853
- }
854
- for (let i = 0; i < ds.length; i++) {
855
- kb.remove(ds[i]);
856
- }
857
- for (let i = 0; i < is.length; i++) {
858
- kb.add(is[i].subject, is[i].predicate, is[i].object, doc);
859
- }
860
- callbackFunction(doc.value, response.ok, response.responseText, response);
861
- }).catch(err => {
862
- callbackFunction(doc.value, false, err.message, err);
863
- });
864
- }
903
+ }, {
904
+ key: "updateDav",
905
+ value: function updateDav(doc, ds, is, callbackFunction) {
906
+ var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
907
+ var kb = this.store;
908
+ // The code below is derived from Kenny's UpdateCenter.js
909
+ var request = kb.any(doc, this.ns.link('request'));
910
+ if (!request) {
911
+ throw new Error('No record of our HTTP GET request for document: ' + doc);
912
+ } // should not happen
913
+ var response = kb.any(request, this.ns.link('response'));
914
+ if (!response) {
915
+ return null; // throw "No record HTTP GET response for document: "+doc
916
+ }
865
917
 
866
- /**
867
- * Likely deprecated, since this lib no longer deals with browser extension
868
- *
869
- * @param doc
870
- * @param ds
871
- * @param is
872
- * @param callbackFunction
873
- * @param options
874
- */
875
- updateLocalFile(doc, ds, is, callbackFunction) {
876
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
877
- const kb = this.store;
878
- // console.log('Writing back to local file\n')
879
-
880
- // prepare contents of revised document
881
- let newSts = kb.statementsMatching(undefined, undefined, undefined, doc).slice(); // copy!
882
-
883
- for (let i = 0; i < ds.length; i++) {
884
- Util.RDFArrayRemove(newSts, ds[i]);
885
- }
886
- for (let i = 0; i < is.length; i++) {
887
- newSts.push(is[i]);
888
- }
889
- // serialize to the appropriate format
890
- var dot = doc.value.lastIndexOf('.');
891
- if (dot < 1) {
892
- throw new Error('Rewriting file: No filename extension: ' + doc.value);
893
- }
894
- var ext = doc.value.slice(dot + 1);
895
- let contentType = Fetcher.CONTENT_TYPE_BY_EXT[ext];
896
- if (!contentType) {
897
- throw new Error('File extension .' + ext + ' not supported for data write');
898
- }
899
- options.body = this.serialize(doc.value, newSts, contentType);
900
- options.contentType = contentType;
901
- kb.fetcher.webOperation('PUT', doc.value, options).then(response => {
902
- if (!response.ok) return callbackFunction(doc.value, false, response.error);
903
- for (let i = 0; i < ds.length; i++) {
904
- kb.remove(ds[i]);
905
- }
906
- for (let i = 0; i < is.length; i++) {
907
- kb.add(is[i].subject, is[i].predicate, is[i].object, doc);
908
- }
909
- callbackFunction(doc.value, true, ''); // success!
910
- });
911
- }
918
+ var contentType = kb.the(response, this.ns.httph('content-type')).value;
912
919
 
913
- /**
914
- * @throws {Error} On unsupported content type
915
- *
916
- * @returns {string}
917
- */
918
- serialize(uri, data, contentType) {
919
- const kb = this.store;
920
- let documentString;
921
- if (typeof data === 'string') {
922
- return data;
923
- }
924
-
925
- // serialize to the appropriate format
926
- var sz = Serializer(kb);
927
- sz.suggestNamespaces(kb.namespaces);
928
- sz.setBase(uri);
929
- switch (contentType) {
930
- case 'text/xml':
931
- case 'application/rdf+xml':
932
- documentString = sz.statementsToXML(data);
933
- break;
934
- case 'text/n3':
935
- case 'text/turtle':
936
- case 'application/x-turtle': // Legacy
937
- case 'application/n3':
938
- // Legacy
939
- documentString = sz.statementsToN3(data);
940
- break;
941
- default:
942
- throw new Error('Content-type ' + contentType + ' not supported for data serialization');
943
- }
944
- return documentString;
945
- }
920
+ // prepare contents of revised document
921
+ var newSts = kb.statementsMatching(undefined, undefined, undefined, doc).slice(); // copy!
922
+ for (var i = 0; i < ds.length; i++) {
923
+ Util.RDFArrayRemove(newSts, ds[i]);
924
+ }
925
+ for (var _i9 = 0; _i9 < is.length; _i9++) {
926
+ newSts.push(is[_i9]);
927
+ }
928
+ var documentString = this.serialize(doc.value, newSts, contentType);
946
929
 
947
- /**
948
- * This is suitable for an initial creation of a document.
949
- */
950
- put(doc, data, contentType, callback) {
951
- const kb = this.store;
952
- let documentString;
953
- return Promise.resolve().then(() => {
954
- documentString = this.serialize(doc.value, data, contentType);
955
- return kb.fetcher.webOperation('PUT', doc.value, {
956
- contentType,
957
- body: documentString
930
+ // Write the new version back
931
+ var candidateTarget = kb.the(response, this.ns.httph('content-location'));
932
+ var targetURI;
933
+ if (candidateTarget) {
934
+ targetURI = uriJoin(candidateTarget.value, targetURI);
935
+ }
936
+ options.contentType = contentType;
937
+ options.noMeta = true;
938
+ options.body = documentString;
939
+ return kb.fetcher.webOperation('PUT', targetURI, options).then(function (response) {
940
+ if (!response.ok) {
941
+ throw new Error(response.error);
942
+ }
943
+ for (var _i10 = 0; _i10 < ds.length; _i10++) {
944
+ kb.remove(ds[_i10]);
945
+ }
946
+ for (var _i11 = 0; _i11 < is.length; _i11++) {
947
+ kb.add(is[_i11].subject, is[_i11].predicate, is[_i11].object, doc);
948
+ }
949
+ callbackFunction(doc.value, response.ok, response.responseText, response);
950
+ }).catch(function (err) {
951
+ callbackFunction(doc.value, false, err.message, err);
958
952
  });
959
- }).then(response => {
960
- if (!response.ok) {
961
- return callback(doc.value, response.ok, response.error, response);
953
+ }
954
+
955
+ /**
956
+ * Likely deprecated, since this lib no longer deals with browser extension
957
+ *
958
+ * @param doc
959
+ * @param ds
960
+ * @param is
961
+ * @param callbackFunction
962
+ * @param options
963
+ */
964
+ }, {
965
+ key: "updateLocalFile",
966
+ value: function updateLocalFile(doc, ds, is, callbackFunction) {
967
+ var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
968
+ var kb = this.store;
969
+ // console.log('Writing back to local file\n')
970
+
971
+ // prepare contents of revised document
972
+ var newSts = kb.statementsMatching(undefined, undefined, undefined, doc).slice(); // copy!
973
+
974
+ for (var i = 0; i < ds.length; i++) {
975
+ Util.RDFArrayRemove(newSts, ds[i]);
976
+ }
977
+ for (var _i12 = 0; _i12 < is.length; _i12++) {
978
+ newSts.push(is[_i12]);
962
979
  }
963
- delete kb.fetcher.nonexistent[doc.value];
964
- delete kb.fetcher.requested[doc.value]; // @@ could this mess with the requested state machine? if a fetch is in progress
980
+ // serialize to the appropriate format
981
+ var dot = doc.value.lastIndexOf('.');
982
+ if (dot < 1) {
983
+ throw new Error('Rewriting file: No filename extension: ' + doc.value);
984
+ }
985
+ var ext = doc.value.slice(dot + 1);
986
+ var contentType = Fetcher.CONTENT_TYPE_BY_EXT[ext];
987
+ if (!contentType) {
988
+ throw new Error('File extension .' + ext + ' not supported for data write');
989
+ }
990
+ options.body = this.serialize(doc.value, newSts, contentType);
991
+ options.contentType = contentType;
992
+ kb.fetcher.webOperation('PUT', doc.value, options).then(function (response) {
993
+ if (!response.ok) return callbackFunction(doc.value, false, response.error);
994
+ for (var _i13 = 0; _i13 < ds.length; _i13++) {
995
+ kb.remove(ds[_i13]);
996
+ }
997
+ for (var _i14 = 0; _i14 < is.length; _i14++) {
998
+ kb.add(is[_i14].subject, is[_i14].predicate, is[_i14].object, doc);
999
+ }
1000
+ callbackFunction(doc.value, true, ''); // success!
1001
+ });
1002
+ }
965
1003
 
966
- if (typeof data !== 'string') {
967
- data.map(st => {
968
- kb.addStatement(st);
969
- });
1004
+ /**
1005
+ * @throws {Error} On unsupported content type
1006
+ *
1007
+ * @returns {string}
1008
+ */
1009
+ }, {
1010
+ key: "serialize",
1011
+ value: function serialize(uri, data, contentType) {
1012
+ var kb = this.store;
1013
+ var documentString;
1014
+ if (typeof data === 'string') {
1015
+ return data;
970
1016
  }
971
- callback(doc.value, response.ok, '', response);
972
- }).catch(err => {
973
- callback(doc.value, false, err.message);
974
- });
975
- }
976
1017
 
977
- /**
978
- * Reloads a document.
979
- *
980
- * Fast and cheap, no metadata. Measure times for the document.
981
- * Load it provisionally.
982
- * Don't delete the statements before the load, or it will leave a broken
983
- * document in the meantime.
984
- *
985
- * @param kb
986
- * @param doc {RDFlibNamedNode}
987
- * @param callbackFunction
988
- */
989
- reload(kb, doc, callbackFunction) {
990
- var startTime = Date.now();
991
- // force sets no-cache and
992
- const options = {
993
- force: true,
994
- noMeta: true,
995
- clearPreviousData: true
996
- };
997
- kb.fetcher.nowOrWhenFetched(doc.value, options, function (ok, body, response) {
998
- if (!ok) {
999
- // console.log(' ERROR reloading data: ' + body)
1000
- callbackFunction(false, 'Error reloading data: ' + body, response);
1001
- //@ts-ignore Where does onErrorWasCalled come from?
1002
- } else if (response.onErrorWasCalled || response.status !== 200) {
1003
- // console.log(' Non-HTTP error reloading data! onErrorWasCalled=' +
1004
- //@ts-ignore Where does onErrorWasCalled come from?
1005
- // response.onErrorWasCalled + ' status: ' + response.status)
1006
- callbackFunction(false, 'Non-HTTP error reloading data: ' + body, response);
1007
- } else {
1008
- var elapsedTimeMs = Date.now() - startTime;
1009
- if (!doc.reloadTimeTotal) doc.reloadTimeTotal = 0;
1010
- if (!doc.reloadTimeCount) doc.reloadTimeCount = 0;
1011
- doc.reloadTimeTotal += elapsedTimeMs;
1012
- doc.reloadTimeCount += 1;
1018
+ // serialize to the appropriate format
1019
+ var sz = Serializer(kb);
1020
+ sz.suggestNamespaces(kb.namespaces);
1021
+ sz.setBase(uri);
1022
+ switch (contentType) {
1023
+ case 'text/xml':
1024
+ case 'application/rdf+xml':
1025
+ documentString = sz.statementsToXML(data);
1026
+ break;
1027
+ case 'text/n3':
1028
+ case 'text/turtle':
1029
+ case 'application/x-turtle': // Legacy
1030
+ case 'application/n3':
1031
+ // Legacy
1032
+ documentString = sz.statementsToN3(data);
1033
+ break;
1034
+ default:
1035
+ throw new Error('Content-type ' + contentType + ' not supported for data serialization');
1036
+ }
1037
+ return documentString;
1038
+ }
1013
1039
 
1014
- // console.log(' Fetch took ' + elapsedTimeMs + 'ms, av. of ' +
1015
- // doc.reloadTimeCount + ' = ' +
1016
- // (doc.reloadTimeTotal / doc.reloadTimeCount) + 'ms.')
1040
+ /**
1041
+ * This is suitable for an initial creation of a document.
1042
+ */
1043
+ }, {
1044
+ key: "put",
1045
+ value: function put(doc, data, contentType, callback) {
1046
+ var _this4 = this;
1047
+ var kb = this.store;
1048
+ var documentString;
1049
+ return Promise.resolve().then(function () {
1050
+ documentString = _this4.serialize(doc.value, data, contentType);
1051
+ return kb.fetcher.webOperation('PUT', doc.value, {
1052
+ contentType: contentType,
1053
+ body: documentString
1054
+ });
1055
+ }).then(function (response) {
1056
+ if (!response.ok) {
1057
+ return callback(doc.value, response.ok, response.error, response);
1058
+ }
1059
+ delete kb.fetcher.nonexistent[doc.value];
1060
+ delete kb.fetcher.requested[doc.value]; // @@ could this mess with the requested state machine? if a fetch is in progress
1017
1061
 
1018
- callbackFunction(true);
1019
- }
1020
- });
1021
- }
1022
- }
1062
+ if (typeof data !== 'string') {
1063
+ data.map(function (st) {
1064
+ kb.addStatement(st);
1065
+ });
1066
+ }
1067
+ callback(doc.value, response.ok, '', response);
1068
+ }).catch(function (err) {
1069
+ callback(doc.value, false, err.message);
1070
+ });
1071
+ }
1072
+
1073
+ /**
1074
+ * Reloads a document.
1075
+ *
1076
+ * Fast and cheap, no metadata. Measure times for the document.
1077
+ * Load it provisionally.
1078
+ * Don't delete the statements before the load, or it will leave a broken
1079
+ * document in the meantime.
1080
+ *
1081
+ * @param kb
1082
+ * @param doc {RDFlibNamedNode}
1083
+ * @param callbackFunction
1084
+ */
1085
+ }, {
1086
+ key: "reload",
1087
+ value: function reload(kb, doc, callbackFunction) {
1088
+ var startTime = Date.now();
1089
+ // force sets no-cache and
1090
+ var options = {
1091
+ force: true,
1092
+ noMeta: true,
1093
+ clearPreviousData: true
1094
+ };
1095
+ kb.fetcher.nowOrWhenFetched(doc.value, options, function (ok, body, response) {
1096
+ if (!ok) {
1097
+ // console.log(' ERROR reloading data: ' + body)
1098
+ callbackFunction(false, 'Error reloading data: ' + body, response);
1099
+ //@ts-ignore Where does onErrorWasCalled come from?
1100
+ } else if (response.onErrorWasCalled || response.status !== 200) {
1101
+ // console.log(' Non-HTTP error reloading data! onErrorWasCalled=' +
1102
+ //@ts-ignore Where does onErrorWasCalled come from?
1103
+ // response.onErrorWasCalled + ' status: ' + response.status)
1104
+ callbackFunction(false, 'Non-HTTP error reloading data: ' + body, response);
1105
+ } else {
1106
+ var elapsedTimeMs = Date.now() - startTime;
1107
+ if (!doc.reloadTimeTotal) doc.reloadTimeTotal = 0;
1108
+ if (!doc.reloadTimeCount) doc.reloadTimeCount = 0;
1109
+ doc.reloadTimeTotal += elapsedTimeMs;
1110
+ doc.reloadTimeCount += 1;
1111
+
1112
+ // console.log(' Fetch took ' + elapsedTimeMs + 'ms, av. of ' +
1113
+ // doc.reloadTimeCount + ' = ' +
1114
+ // (doc.reloadTimeTotal / doc.reloadTimeCount) + 'ms.')
1115
+
1116
+ callbackFunction(true);
1117
+ }
1118
+ });
1119
+ }
1120
+ }]);
1121
+ return UpdateManager;
1122
+ }();
1123
+ export { UpdateManager as default };