rdflib 2.2.30-8a42dd57 → 2.2.30-8d9b0099

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/fetcher.js CHANGED
@@ -598,7 +598,9 @@ var Fetcher = /*#__PURE__*/function () {
598
598
  if (!this._fetch) {
599
599
  throw new Error('No _fetch function available for Fetcher');
600
600
  }
601
- this.appNode = this.store.rdfFactory.blankNode();
601
+ // This is the name of the graphh we store all the HTTP metadata in
602
+ this.appNode = this.store.sym('chrome://TheCurrentSession');
603
+ // this.appNode = this.store.rdfFactory.blankNode() // Needs to have a URI in tests
602
604
  this.store.fetcher = this; // Bi-linked
603
605
  this.requested = {};
604
606
  this.timeouts = {};
@@ -1,7 +1,9 @@
1
1
  import _typeof from "@babel/runtime/helpers/typeof";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
3
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
4
  import _createClass from "@babel/runtime/helpers/createClass";
4
5
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
5
7
  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
8
  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
9
  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; }
@@ -76,13 +78,88 @@ var UpdateManager = /*#__PURE__*/function () {
76
78
  return uri.slice(0, 4) === 'http';
77
79
  }
78
80
 
81
+ /** Remove from the store HTTP authorization metadata
82
+ * The editble function below relies on copies we have in the store
83
+ * of the results of previous HTTP transactions. Howver, when
84
+ * the user logs in, then that data misrepresents what would happen
85
+ * if the user tried again.
86
+ */
87
+ }, {
88
+ key: "flagAuthorizationMetadata",
89
+ value: function flagAuthorizationMetadata() {
90
+ var kb = this.store;
91
+ var meta = kb.fetcher.appNode;
92
+ var requests = kb.statementsMatching(undefined, this.ns.link('requestedURI'), undefined, meta).map(function (st) {
93
+ return st.subject;
94
+ });
95
+ var _iterator = _createForOfIteratorHelper(requests),
96
+ _step;
97
+ try {
98
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
99
+ var request = _step.value;
100
+ var _response = kb.any(request, this.ns.link('response'), null, meta);
101
+ if (_response !== undefined) {
102
+ // ts
103
+ this.store.add(_response, this.ns.link('outOfDate'), true, meta); // @@ Boolean is fine - fix types
104
+ }
105
+ }
106
+ } catch (err) {
107
+ _iterator.e(err);
108
+ } finally {
109
+ _iterator.f();
110
+ }
111
+ }
112
+
79
113
  /**
80
114
  * Tests whether a file is editable.
81
115
  * If the file has a specific annotation that it is machine written,
82
116
  * for safety, it is editable (this doesn't actually check for write access)
83
117
  * If the file has wac-allow and accept patch headers, those are respected.
84
118
  * and local write access is determined by those headers.
85
- * This version only looks at past HTTP requests, does not make new ones.
119
+ * This async version not only looks at past HTTP requests, it also makes new ones if necessary.
120
+ *
121
+ * @returns The method string SPARQL or DAV or
122
+ * LOCALFILE or false if known, undefined if not known.
123
+ */
124
+ }, {
125
+ key: "checkEditable",
126
+ value: function () {
127
+ var _checkEditable = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(uri, kb) {
128
+ var initial, final;
129
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
130
+ while (1) switch (_context.prev = _context.next) {
131
+ case 0:
132
+ initial = this.editable(uri, kb);
133
+ if (!(initial !== undefined)) {
134
+ _context.next = 3;
135
+ break;
136
+ }
137
+ return _context.abrupt("return", initial);
138
+ case 3:
139
+ _context.next = 5;
140
+ return this.store.fetcher.load(uri);
141
+ case 5:
142
+ final = this.editable(uri, kb);
143
+ console.log("Loaded ".concat(uri, " just to check editable, result: ").concat(final, "."));
144
+ return _context.abrupt("return", final);
145
+ case 8:
146
+ case "end":
147
+ return _context.stop();
148
+ }
149
+ }, _callee, this);
150
+ }));
151
+ function checkEditable(_x, _x2) {
152
+ return _checkEditable.apply(this, arguments);
153
+ }
154
+ return checkEditable;
155
+ }()
156
+ /**
157
+ * Tests whether a file is editable.
158
+ * If the file has a specific annotation that it is machine written,
159
+ * for safety, it is editable (this doesn't actually check for write access)
160
+ * If the file has wac-allow and accept patch headers, those are respected.
161
+ * and local write access is determined by those headers.
162
+ * This synchronous version only looks at past HTTP requests, does not make new ones.
86
163
  *
87
164
  * @returns The method string SPARQL or DAV or
88
165
  * LOCALFILE or false if known, undefined if not known.
@@ -99,27 +176,34 @@ var UpdateManager = /*#__PURE__*/function () {
99
176
  }
100
177
  uri = termValue(uri);
101
178
  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'))) {
179
+ if (this.store.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
180
  return 'LOCALFILE';
104
181
  }
105
182
  }
106
183
  var request;
107
184
  var definitive = false;
185
+ var meta = this.store.fetcher.appNode;
186
+ // const kb = s
187
+
108
188
  // @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));
189
+ var requests = kb.each(undefined, this.ns.link('requestedURI'), docpart(uri), meta);
110
190
  var method;
111
191
  for (var r = 0; r < requests.length; r++) {
112
192
  request = requests[r];
113
193
  if (request !== undefined) {
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'));
194
+ var _response2 = kb.any(request, this.ns.link('response'));
195
+ if (_response2 !== undefined) {
196
+ // ts
197
+
198
+ var outOfDate = kb.anyJS(_response2, this.ns.link('outOfDate'));
199
+ if (outOfDate) continue;
200
+ var wacAllow = kb.anyValue(_response2, this.ns.httph('wac-allow'));
117
201
  if (wacAllow) {
118
- var _iterator = _createForOfIteratorHelper(wacAllow.split(',')),
119
- _step;
202
+ var _iterator2 = _createForOfIteratorHelper(wacAllow.split(',')),
203
+ _step2;
120
204
  try {
121
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
122
- var bit = _step.value;
205
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
206
+ var bit = _step2.value;
123
207
  var lr = bit.split('=');
124
208
  if (lr[0].includes('user') && !lr[1].includes('write') && !lr[1].includes('append')) {
125
209
  // console.log(' editable? excluded by WAC-Allow: ', wacAllow)
@@ -127,12 +211,12 @@ var UpdateManager = /*#__PURE__*/function () {
127
211
  }
128
212
  }
129
213
  } catch (err) {
130
- _iterator.e(err);
214
+ _iterator2.e(err);
131
215
  } finally {
132
- _iterator.f();
216
+ _iterator2.f();
133
217
  }
134
218
  }
135
- var acceptPatch = kb.each(response, this.ns.httph('accept-patch'));
219
+ var acceptPatch = kb.each(_response2, this.ns.httph('accept-patch'));
136
220
  if (acceptPatch.length) {
137
221
  for (var i = 0; i < acceptPatch.length; i++) {
138
222
  method = acceptPatch[i].value.trim();
@@ -140,7 +224,7 @@ var UpdateManager = /*#__PURE__*/function () {
140
224
  if (method.indexOf('application/sparql-update-single-match') >= 0) return 'SPARQL';
141
225
  }
142
226
  }
143
- var authorVia = kb.each(response, this.ns.httph('ms-author-via'));
227
+ var authorVia = kb.each(_response2, this.ns.httph('ms-author-via'));
144
228
  if (authorVia.length) {
145
229
  for (var _i = 0; _i < authorVia.length; _i++) {
146
230
  method = authorVia[_i].value.trim();
@@ -155,7 +239,7 @@ var UpdateManager = /*#__PURE__*/function () {
155
239
  if (!this.isHttpUri(uri)) {
156
240
  if (!wacAllow) return false;else return 'LOCALFILE';
157
241
  }
158
- var status = kb.each(response, this.ns.http('status'));
242
+ var status = kb.each(_response2, this.ns.http('status'));
159
243
  if (status.length) {
160
244
  for (var _i2 = 0; _i2 < status.length; _i2++) {
161
245
  // @ts-ignore since statuses should be TFTerms, this should always be false
package/lib/fetcher.d.ts CHANGED
@@ -181,7 +181,7 @@ export default class Fetcher implements CallbackifyInterface {
181
181
  _fetch: Fetch;
182
182
  mediatypes: MediatypesMap;
183
183
  /** Denoting this session */
184
- appNode: BlankNode;
184
+ appNode: NamedNode;
185
185
  /**
186
186
  * this.requested[uri] states:
187
187
  * undefined no record of web access or records reset
package/lib/fetcher.js CHANGED
@@ -581,7 +581,9 @@ var Fetcher = /*#__PURE__*/function () {
581
581
  if (!this._fetch) {
582
582
  throw new Error('No _fetch function available for Fetcher');
583
583
  }
584
- this.appNode = this.store.rdfFactory.blankNode();
584
+ // This is the name of the graphh we store all the HTTP metadata in
585
+ this.appNode = this.store.sym('chrome://TheCurrentSession');
586
+ // this.appNode = this.store.rdfFactory.blankNode() // Needs to have a URI in tests
585
587
  this.store.fetcher = this; // Bi-linked
586
588
  this.requested = {};
587
589
  this.timeouts = {};
@@ -27,13 +27,32 @@ export default class UpdateManager {
27
27
  constructor(store?: IndexedFormula);
28
28
  patchControlFor(doc: NamedNode): any;
29
29
  isHttpUri(uri: string): boolean;
30
+ /** Remove from the store HTTP authorization metadata
31
+ * The editble function below relies on copies we have in the store
32
+ * of the results of previous HTTP transactions. Howver, when
33
+ * the user logs in, then that data misrepresents what would happen
34
+ * if the user tried again.
35
+ */
36
+ flagAuthorizationMetadata(): void;
37
+ /**
38
+ * Tests whether a file is editable.
39
+ * If the file has a specific annotation that it is machine written,
40
+ * for safety, it is editable (this doesn't actually check for write access)
41
+ * If the file has wac-allow and accept patch headers, those are respected.
42
+ * and local write access is determined by those headers.
43
+ * This async version not only looks at past HTTP requests, it also makes new ones if necessary.
44
+ *
45
+ * @returns The method string SPARQL or DAV or
46
+ * LOCALFILE or false if known, undefined if not known.
47
+ */
48
+ checkEditable(uri: string | NamedNode, kb?: IndexedFormula): Promise<string | boolean | undefined>;
30
49
  /**
31
50
  * Tests whether a file is editable.
32
51
  * If the file has a specific annotation that it is machine written,
33
52
  * for safety, it is editable (this doesn't actually check for write access)
34
53
  * If the file has wac-allow and accept patch headers, those are respected.
35
54
  * and local write access is determined by those headers.
36
- * This version only looks at past HTTP requests, does not make new ones.
55
+ * This synchronous version only looks at past HTTP requests, does not make new ones.
37
56
  *
38
57
  * @returns The method string SPARQL or DAV or
39
58
  * LOCALFILE or false if known, undefined if not known.
@@ -6,7 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.default = void 0;
9
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
10
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
12
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
13
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
12
14
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
@@ -80,13 +82,88 @@ var UpdateManager = /*#__PURE__*/function () {
80
82
  return uri.slice(0, 4) === 'http';
81
83
  }
82
84
 
85
+ /** Remove from the store HTTP authorization metadata
86
+ * The editble function below relies on copies we have in the store
87
+ * of the results of previous HTTP transactions. Howver, when
88
+ * the user logs in, then that data misrepresents what would happen
89
+ * if the user tried again.
90
+ */
91
+ }, {
92
+ key: "flagAuthorizationMetadata",
93
+ value: function flagAuthorizationMetadata() {
94
+ var kb = this.store;
95
+ var meta = kb.fetcher.appNode;
96
+ var requests = kb.statementsMatching(undefined, this.ns.link('requestedURI'), undefined, meta).map(function (st) {
97
+ return st.subject;
98
+ });
99
+ var _iterator = _createForOfIteratorHelper(requests),
100
+ _step;
101
+ try {
102
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
103
+ var request = _step.value;
104
+ var _response = kb.any(request, this.ns.link('response'), null, meta);
105
+ if (_response !== undefined) {
106
+ // ts
107
+ this.store.add(_response, this.ns.link('outOfDate'), true, meta); // @@ Boolean is fine - fix types
108
+ }
109
+ }
110
+ } catch (err) {
111
+ _iterator.e(err);
112
+ } finally {
113
+ _iterator.f();
114
+ }
115
+ }
116
+
83
117
  /**
84
118
  * Tests whether a file is editable.
85
119
  * If the file has a specific annotation that it is machine written,
86
120
  * for safety, it is editable (this doesn't actually check for write access)
87
121
  * If the file has wac-allow and accept patch headers, those are respected.
88
122
  * and local write access is determined by those headers.
89
- * This version only looks at past HTTP requests, does not make new ones.
123
+ * This async version not only looks at past HTTP requests, it also makes new ones if necessary.
124
+ *
125
+ * @returns The method string SPARQL or DAV or
126
+ * LOCALFILE or false if known, undefined if not known.
127
+ */
128
+ }, {
129
+ key: "checkEditable",
130
+ value: function () {
131
+ var _checkEditable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(uri, kb) {
132
+ var initial, final;
133
+ return _regenerator.default.wrap(function _callee$(_context) {
134
+ while (1) switch (_context.prev = _context.next) {
135
+ case 0:
136
+ initial = this.editable(uri, kb);
137
+ if (!(initial !== undefined)) {
138
+ _context.next = 3;
139
+ break;
140
+ }
141
+ return _context.abrupt("return", initial);
142
+ case 3:
143
+ _context.next = 5;
144
+ return this.store.fetcher.load(uri);
145
+ case 5:
146
+ final = this.editable(uri, kb);
147
+ console.log("Loaded ".concat(uri, " just to check editable, result: ").concat(final, "."));
148
+ return _context.abrupt("return", final);
149
+ case 8:
150
+ case "end":
151
+ return _context.stop();
152
+ }
153
+ }, _callee, this);
154
+ }));
155
+ function checkEditable(_x, _x2) {
156
+ return _checkEditable.apply(this, arguments);
157
+ }
158
+ return checkEditable;
159
+ }()
160
+ /**
161
+ * Tests whether a file is editable.
162
+ * If the file has a specific annotation that it is machine written,
163
+ * for safety, it is editable (this doesn't actually check for write access)
164
+ * If the file has wac-allow and accept patch headers, those are respected.
165
+ * and local write access is determined by those headers.
166
+ * This synchronous version only looks at past HTTP requests, does not make new ones.
90
167
  *
91
168
  * @returns The method string SPARQL or DAV or
92
169
  * LOCALFILE or false if known, undefined if not known.
@@ -103,27 +180,34 @@ var UpdateManager = /*#__PURE__*/function () {
103
180
  }
104
181
  uri = (0, _termValue.termValue)(uri);
105
182
  if (!this.isHttpUri(uri)) {
106
- 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'))) {
183
+ if (this.store.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'))) {
107
184
  return 'LOCALFILE';
108
185
  }
109
186
  }
110
187
  var request;
111
188
  var definitive = false;
189
+ var meta = this.store.fetcher.appNode;
190
+ // const kb = s
191
+
112
192
  // @ts-ignore passes a string to kb.each, which expects a term. Should this work?
113
- var requests = kb.each(undefined, this.ns.link('requestedURI'), (0, _uri.docpart)(uri));
193
+ var requests = kb.each(undefined, this.ns.link('requestedURI'), (0, _uri.docpart)(uri), meta);
114
194
  var method;
115
195
  for (var r = 0; r < requests.length; r++) {
116
196
  request = requests[r];
117
197
  if (request !== undefined) {
118
- var response = kb.any(request, this.ns.link('response'));
119
- if (request !== undefined) {
120
- var wacAllow = kb.anyValue(response, this.ns.httph('wac-allow'));
198
+ var _response2 = kb.any(request, this.ns.link('response'));
199
+ if (_response2 !== undefined) {
200
+ // ts
201
+
202
+ var outOfDate = kb.anyJS(_response2, this.ns.link('outOfDate'));
203
+ if (outOfDate) continue;
204
+ var wacAllow = kb.anyValue(_response2, this.ns.httph('wac-allow'));
121
205
  if (wacAllow) {
122
- var _iterator = _createForOfIteratorHelper(wacAllow.split(',')),
123
- _step;
206
+ var _iterator2 = _createForOfIteratorHelper(wacAllow.split(',')),
207
+ _step2;
124
208
  try {
125
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
126
- var bit = _step.value;
209
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
210
+ var bit = _step2.value;
127
211
  var lr = bit.split('=');
128
212
  if (lr[0].includes('user') && !lr[1].includes('write') && !lr[1].includes('append')) {
129
213
  // console.log(' editable? excluded by WAC-Allow: ', wacAllow)
@@ -131,12 +215,12 @@ var UpdateManager = /*#__PURE__*/function () {
131
215
  }
132
216
  }
133
217
  } catch (err) {
134
- _iterator.e(err);
218
+ _iterator2.e(err);
135
219
  } finally {
136
- _iterator.f();
220
+ _iterator2.f();
137
221
  }
138
222
  }
139
- var acceptPatch = kb.each(response, this.ns.httph('accept-patch'));
223
+ var acceptPatch = kb.each(_response2, this.ns.httph('accept-patch'));
140
224
  if (acceptPatch.length) {
141
225
  for (var i = 0; i < acceptPatch.length; i++) {
142
226
  method = acceptPatch[i].value.trim();
@@ -144,7 +228,7 @@ var UpdateManager = /*#__PURE__*/function () {
144
228
  if (method.indexOf('application/sparql-update-single-match') >= 0) return 'SPARQL';
145
229
  }
146
230
  }
147
- var authorVia = kb.each(response, this.ns.httph('ms-author-via'));
231
+ var authorVia = kb.each(_response2, this.ns.httph('ms-author-via'));
148
232
  if (authorVia.length) {
149
233
  for (var _i = 0; _i < authorVia.length; _i++) {
150
234
  method = authorVia[_i].value.trim();
@@ -159,7 +243,7 @@ var UpdateManager = /*#__PURE__*/function () {
159
243
  if (!this.isHttpUri(uri)) {
160
244
  if (!wacAllow) return false;else return 'LOCALFILE';
161
245
  }
162
- var status = kb.each(response, this.ns.http('status'));
246
+ var status = kb.each(_response2, this.ns.http('status'));
163
247
  if (status.length) {
164
248
  for (var _i2 = 0; _i2 < status.length; _i2++) {
165
249
  // @ts-ignore since statuses should be TFTerms, this should always be false
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rdflib",
3
3
  "description": "an RDF library for node.js. Suitable for client and server side.",
4
- "version": "2.2.30-8a42dd57",
4
+ "version": "2.2.30-8d9b0099",
5
5
  "private": false,
6
6
  "browserslist": [
7
7
  "> 0.5%"
package/src/fetcher.ts CHANGED
@@ -721,7 +721,7 @@ export default class Fetcher implements CallbackifyInterface {
721
721
  _fetch: Fetch
722
722
  mediatypes: MediatypesMap
723
723
  /** Denoting this session */
724
- appNode: BlankNode
724
+ appNode: NamedNode
725
725
  /**
726
726
  * this.requested[uri] states:
727
727
  * undefined no record of web access or records reset
@@ -771,8 +771,9 @@ export default class Fetcher implements CallbackifyInterface {
771
771
  if (!this._fetch) {
772
772
  throw new Error('No _fetch function available for Fetcher')
773
773
  }
774
-
775
- this.appNode = this.store.rdfFactory.blankNode()
774
+ // This is the name of the graphh we store all the HTTP metadata in
775
+ this.appNode = this.store.sym('chrome://TheCurrentSession')
776
+ // this.appNode = this.store.rdfFactory.blankNode() // Needs to have a URI in tests
776
777
  this.store.fetcher = this // Bi-linked
777
778
  this.requested = {}
778
779
  this.timeouts = {}
@@ -81,14 +81,52 @@ export default class UpdateManager {
81
81
  return( uri.slice(0,4) === 'http' )
82
82
  }
83
83
 
84
+ /** Remove from the store HTTP authorization metadata
85
+ * The editble function below relies on copies we have in the store
86
+ * of the results of previous HTTP transactions. Howver, when
87
+ * the user logs in, then that data misrepresents what would happen
88
+ * if the user tried again.
89
+ */
90
+ flagAuthorizationMetadata () {
91
+ const kb = this.store
92
+ const meta = kb.fetcher.appNode
93
+ const requests = kb.statementsMatching(undefined, this.ns.link('requestedURI'), undefined, meta).map(st => st.subject)
94
+ for (const request of requests) {
95
+ const response = kb.any(request, this.ns.link('response'), null, meta) as Quad_Subject
96
+ if (response !== undefined) { // ts
97
+ this.store.add(response, this.ns.link('outOfDate'), true as any, meta) // @@ Boolean is fine - fix types
98
+ }
99
+ }
100
+ }
84
101
 
102
+ /**
103
+ * Tests whether a file is editable.
104
+ * If the file has a specific annotation that it is machine written,
105
+ * for safety, it is editable (this doesn't actually check for write access)
106
+ * If the file has wac-allow and accept patch headers, those are respected.
107
+ * and local write access is determined by those headers.
108
+ * This async version not only looks at past HTTP requests, it also makes new ones if necessary.
109
+ *
110
+ * @returns The method string SPARQL or DAV or
111
+ * LOCALFILE or false if known, undefined if not known.
112
+ */
113
+ async checkEditable (uri: string | NamedNode, kb?: IndexedFormula): Promise<string | boolean | undefined> {
114
+ const initial = this.editable(uri, kb)
115
+ if (initial !== undefined) {
116
+ return initial
117
+ }
118
+ await this.store.fetcher.load(uri)
119
+ const final = this.editable(uri, kb)
120
+ console.log(`Loaded ${uri} just to check editable, result: ${final}.`)
121
+ return final
122
+ }
85
123
  /**
86
124
  * Tests whether a file is editable.
87
125
  * If the file has a specific annotation that it is machine written,
88
126
  * for safety, it is editable (this doesn't actually check for write access)
89
127
  * If the file has wac-allow and accept patch headers, those are respected.
90
128
  * and local write access is determined by those headers.
91
- * This version only looks at past HTTP requests, does not make new ones.
129
+ * This synchronous version only looks at past HTTP requests, does not make new ones.
92
130
  *
93
131
  * @returns The method string SPARQL or DAV or
94
132
  * LOCALFILE or false if known, undefined if not known.
@@ -103,7 +141,7 @@ export default class UpdateManager {
103
141
  uri = termValue(uri)
104
142
 
105
143
  if ( !this.isHttpUri(uri as string) ) {
106
- if (kb.holds(
144
+ if (this.store.holds(
107
145
  this.store.rdfFactory.namedNode(uri),
108
146
  this.store.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
109
147
  this.store.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#MachineEditableDocument'))) {
@@ -113,14 +151,21 @@ export default class UpdateManager {
113
151
 
114
152
  var request
115
153
  var definitive = false
154
+ const meta = this.store.fetcher.appNode
155
+ // const kb = s
156
+
116
157
  // @ts-ignore passes a string to kb.each, which expects a term. Should this work?
117
- var requests = kb.each(undefined, this.ns.link('requestedURI'), docpart(uri))
158
+ var requests = kb.each(undefined, this.ns.link('requestedURI'), docpart(uri), meta)
118
159
  var method: string
119
160
  for (var r = 0; r < requests.length; r++) {
120
161
  request = requests[r]
121
162
  if (request !== undefined) {
122
- var response = kb.any(request, this.ns.link('response')) as Quad_Subject
123
- if (request !== undefined) {
163
+ const response = kb.any(request, this.ns.link('response')) as Quad_Subject
164
+ if (response !== undefined) { // ts
165
+
166
+ const outOfDate = kb.anyJS(response, this.ns.link('outOfDate')) as Quad_Subject
167
+ if (outOfDate) continue
168
+
124
169
  var wacAllow = kb.anyValue(response, this.ns.httph('wac-allow'))
125
170
  if (wacAllow) {
126
171
  for (var bit of wacAllow.split(',')) {