wao 0.6.1 → 0.6.2
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/cjs/aoconnect.js +60 -60
- package/cjs/lua/weavedb_mock.lua +43 -0
- package/cjs/server.js +3 -1
- package/cjs/tao.js +3 -1
- package/cjs/{kv.js → weavedb.js} +227 -115
- package/cjs/weavedrive.js +6 -5
- package/esm/aoconnect.js +4 -6
- package/esm/lua/weavedb_mock.lua +43 -0
- package/esm/server.js +1 -1
- package/esm/tao.js +1 -1
- package/esm/{kv.js → weavedb.js} +119 -36
- package/esm/weavedrive.js +8 -16
- package/package.json +1 -1
package/cjs/aoconnect.js
CHANGED
|
@@ -11,7 +11,6 @@ var _base64url = _interopRequireDefault(require("base64url"));
|
|
|
11
11
|
var _utils = require("./utils.js");
|
|
12
12
|
var _armem = _interopRequireDefault(require("./armem.js"));
|
|
13
13
|
var _weavedrive = _interopRequireDefault(require("./weavedrive.js"));
|
|
14
|
-
var _kv = _interopRequireDefault(require("./kv.js"));
|
|
15
14
|
var _aoLoader = _interopRequireDefault(require("@permaweb/ao-loader"));
|
|
16
15
|
var _fs = require("fs");
|
|
17
16
|
var _path = require("path");
|
|
@@ -39,9 +38,12 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
|
|
|
39
38
|
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
40
39
|
var pkg = (_WarpArBundles$defaul = WarpArBundles["default"]) !== null && _WarpArBundles$defaul !== void 0 ? _WarpArBundles$defaul : WarpArBundles;
|
|
41
40
|
var DataItem = pkg.DataItem;
|
|
42
|
-
var connect = exports.connect = function connect(mem) {
|
|
41
|
+
var connect = exports.connect = function connect(mem, _ref) {
|
|
43
42
|
var _mem;
|
|
44
|
-
var log =
|
|
43
|
+
var _ref$log = _ref.log,
|
|
44
|
+
log = _ref$log === void 0 ? false : _ref$log,
|
|
45
|
+
_ref$extensions = _ref.extensions,
|
|
46
|
+
extensions = _ref$extensions === void 0 ? {} : _ref$extensions;
|
|
45
47
|
var isMem = ((_mem = mem) === null || _mem === void 0 ? void 0 : _mem.__type__) === "mem";
|
|
46
48
|
if (!isMem) {
|
|
47
49
|
var _mem2;
|
|
@@ -56,18 +58,18 @@ var connect = exports.connect = function connect(mem) {
|
|
|
56
58
|
mem: mem,
|
|
57
59
|
log: log
|
|
58
60
|
});
|
|
59
|
-
var
|
|
60
|
-
|
|
61
|
+
for (var k in extensions) extensions[k] = new extensions[k](ar).ext;
|
|
62
|
+
extensions.WeaveDrive = new _weavedrive["default"](ar).ext;
|
|
61
63
|
var transform = function transform(input) {
|
|
62
64
|
var _input$Tags;
|
|
63
65
|
var output = {
|
|
64
66
|
Tags: []
|
|
65
67
|
};
|
|
66
68
|
if (input.Data) output.Data = input.Data;
|
|
67
|
-
Object.entries(input).forEach(function (
|
|
68
|
-
var
|
|
69
|
-
key =
|
|
70
|
-
value =
|
|
69
|
+
Object.entries(input).forEach(function (_ref2) {
|
|
70
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
71
|
+
key = _ref3[0],
|
|
72
|
+
value = _ref3[1];
|
|
71
73
|
if (key !== "Data" && key !== "Tags" && typeof value === "string") {
|
|
72
74
|
output.Tags.push({
|
|
73
75
|
name: key,
|
|
@@ -103,14 +105,14 @@ var connect = exports.connect = function connect(mem) {
|
|
|
103
105
|
Tags: Tags !== null && Tags !== void 0 && Tags.length ? Tags : []
|
|
104
106
|
};
|
|
105
107
|
};
|
|
106
|
-
var genEnv = function genEnv(
|
|
107
|
-
var pid =
|
|
108
|
-
|
|
109
|
-
owner =
|
|
110
|
-
|
|
111
|
-
module =
|
|
112
|
-
|
|
113
|
-
auth =
|
|
108
|
+
var genEnv = function genEnv(_ref4) {
|
|
109
|
+
var pid = _ref4.pid,
|
|
110
|
+
_ref4$owner = _ref4.owner,
|
|
111
|
+
owner = _ref4$owner === void 0 ? "" : _ref4$owner,
|
|
112
|
+
_ref4$module = _ref4.module,
|
|
113
|
+
module = _ref4$module === void 0 ? "" : _ref4$module,
|
|
114
|
+
_ref4$auth = _ref4.auth,
|
|
115
|
+
auth = _ref4$auth === void 0 ? "" : _ref4$auth;
|
|
114
116
|
return {
|
|
115
117
|
Process: {
|
|
116
118
|
Id: pid,
|
|
@@ -145,7 +147,7 @@ var connect = exports.connect = function connect(mem) {
|
|
|
145
147
|
};
|
|
146
148
|
};
|
|
147
149
|
var spawn = /*#__PURE__*/function () {
|
|
148
|
-
var
|
|
150
|
+
var _ref5 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
149
151
|
var _opt$module, _mem$wasms$mod, _format, _opt$tags, _opt$tags2;
|
|
150
152
|
var opt,
|
|
151
153
|
mod,
|
|
@@ -165,7 +167,6 @@ var connect = exports.connect = function connect(mem) {
|
|
|
165
167
|
__tags,
|
|
166
168
|
now,
|
|
167
169
|
t,
|
|
168
|
-
wd,
|
|
169
170
|
handle,
|
|
170
171
|
_tags,
|
|
171
172
|
res,
|
|
@@ -184,7 +185,7 @@ var connect = exports.connect = function connect(mem) {
|
|
|
184
185
|
unit,
|
|
185
186
|
_int,
|
|
186
187
|
cronTags,
|
|
187
|
-
|
|
188
|
+
_k,
|
|
188
189
|
_args = arguments;
|
|
189
190
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
190
191
|
while (1) switch (_context.prev = _context.next) {
|
|
@@ -274,16 +275,15 @@ var connect = exports.connect = function connect(mem) {
|
|
|
274
275
|
case 33:
|
|
275
276
|
now = Date.now;
|
|
276
277
|
t = (0, _utils.tags)(opt.tags);
|
|
277
|
-
|
|
278
|
-
_context.next = 38;
|
|
278
|
+
_context.next = 37;
|
|
279
279
|
return (0, _aoLoader["default"])(wasm, {
|
|
280
280
|
format: format,
|
|
281
|
-
WeaveDrive:
|
|
281
|
+
WeaveDrive: extensions[t.Extension],
|
|
282
282
|
spawn: item,
|
|
283
283
|
module: mem.txs[mod],
|
|
284
284
|
blockHeight: "100"
|
|
285
285
|
});
|
|
286
|
-
case
|
|
286
|
+
case 37:
|
|
287
287
|
handle = _context.sent;
|
|
288
288
|
_module = {
|
|
289
289
|
handle: handle,
|
|
@@ -308,7 +308,7 @@ var connect = exports.connect = function connect(mem) {
|
|
|
308
308
|
opt: opt
|
|
309
309
|
};
|
|
310
310
|
if (!(_tags["On-Boot"] || true)) {
|
|
311
|
-
_context.next =
|
|
311
|
+
_context.next = 58;
|
|
312
312
|
break;
|
|
313
313
|
}
|
|
314
314
|
data = "";
|
|
@@ -321,72 +321,72 @@ var connect = exports.connect = function connect(mem) {
|
|
|
321
321
|
auth: _test.mu.addr
|
|
322
322
|
});
|
|
323
323
|
_t = (0, _utils.tags)(msg.Tags);
|
|
324
|
-
_context.next =
|
|
324
|
+
_context.next = 52;
|
|
325
325
|
return _module.handle(null, msg, _env);
|
|
326
|
-
case
|
|
326
|
+
case 52:
|
|
327
327
|
res = _context.sent;
|
|
328
328
|
p.memory = res.Memory;
|
|
329
329
|
delete res.Memory;
|
|
330
330
|
p.res[id] = res;
|
|
331
|
-
_context.next =
|
|
331
|
+
_context.next = 59;
|
|
332
332
|
break;
|
|
333
|
-
case
|
|
333
|
+
case 58:
|
|
334
334
|
p.height += 1;
|
|
335
|
-
case
|
|
335
|
+
case 59:
|
|
336
336
|
mem.msgs[id] = opt;
|
|
337
337
|
mem.env[id] = p;
|
|
338
338
|
if (!_tags["Cron-Interval"]) {
|
|
339
|
-
_context.next =
|
|
339
|
+
_context.next = 85;
|
|
340
340
|
break;
|
|
341
341
|
}
|
|
342
342
|
_tags$CronInterval$s = _tags["Cron-Interval"].split("-"), _tags$CronInterval$s2 = _slicedToArray(_tags$CronInterval$s, 2), num = _tags$CronInterval$s2[0], unit = _tags$CronInterval$s2[1];
|
|
343
343
|
_int = 0;
|
|
344
344
|
_context.t0 = unit.replace(/s$/, "");
|
|
345
|
-
_context.next = _context.t0 === "millisecond" ?
|
|
345
|
+
_context.next = _context.t0 === "millisecond" ? 67 : _context.t0 === "second" ? 69 : _context.t0 === "minute" ? 71 : _context.t0 === "hour" ? 73 : _context.t0 === "day" ? 75 : _context.t0 === "month" ? 77 : _context.t0 === "year" ? 79 : 81;
|
|
346
346
|
break;
|
|
347
|
-
case
|
|
347
|
+
case 67:
|
|
348
348
|
_int = num;
|
|
349
|
-
return _context.abrupt("break",
|
|
350
|
-
case
|
|
349
|
+
return _context.abrupt("break", 81);
|
|
350
|
+
case 69:
|
|
351
351
|
_int = num * 1000;
|
|
352
|
-
return _context.abrupt("break",
|
|
353
|
-
case
|
|
352
|
+
return _context.abrupt("break", 81);
|
|
353
|
+
case 71:
|
|
354
354
|
_int = num * 1000 * 60;
|
|
355
|
-
return _context.abrupt("break",
|
|
356
|
-
case
|
|
355
|
+
return _context.abrupt("break", 81);
|
|
356
|
+
case 73:
|
|
357
357
|
_int = num * 1000 * 60 * 60;
|
|
358
|
-
return _context.abrupt("break",
|
|
359
|
-
case
|
|
358
|
+
return _context.abrupt("break", 81);
|
|
359
|
+
case 75:
|
|
360
360
|
_int = num * 1000 * 60 * 60 * 24;
|
|
361
|
-
return _context.abrupt("break",
|
|
362
|
-
case
|
|
361
|
+
return _context.abrupt("break", 81);
|
|
362
|
+
case 77:
|
|
363
363
|
_int = num * 1000 * 60 * 60 * 24 * 30;
|
|
364
|
-
return _context.abrupt("break",
|
|
365
|
-
case
|
|
364
|
+
return _context.abrupt("break", 81);
|
|
365
|
+
case 79:
|
|
366
366
|
_int = num * 1000 * 60 * 60 * 24 * 365;
|
|
367
|
-
return _context.abrupt("break",
|
|
368
|
-
case
|
|
367
|
+
return _context.abrupt("break", 81);
|
|
368
|
+
case 81:
|
|
369
369
|
cronTags = [];
|
|
370
|
-
for (
|
|
371
|
-
if (/^Cron-Tag-/.test(
|
|
370
|
+
for (_k in _tags) {
|
|
371
|
+
if (/^Cron-Tag-/.test(_k)) {
|
|
372
372
|
cronTags.push({
|
|
373
|
-
name:
|
|
374
|
-
value: _tags[
|
|
373
|
+
name: _k.replace(/Cron-Tag-/, ""),
|
|
374
|
+
value: _tags[_k]
|
|
375
375
|
});
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
378
|
mem.env[id].cronTags = cronTags;
|
|
379
379
|
mem.env[id].span = _int;
|
|
380
|
-
case
|
|
380
|
+
case 85:
|
|
381
381
|
return _context.abrupt("return", id);
|
|
382
|
-
case
|
|
382
|
+
case 86:
|
|
383
383
|
case "end":
|
|
384
384
|
return _context.stop();
|
|
385
385
|
}
|
|
386
386
|
}, _callee);
|
|
387
387
|
}));
|
|
388
388
|
return function spawn() {
|
|
389
|
-
return
|
|
389
|
+
return _ref5.apply(this, arguments);
|
|
390
390
|
};
|
|
391
391
|
}();
|
|
392
392
|
function genHashChain(previousHash) {
|
|
@@ -399,9 +399,9 @@ var connect = exports.connect = function connect(mem) {
|
|
|
399
399
|
return (0, _base64url["default"])(hasher.digest());
|
|
400
400
|
}
|
|
401
401
|
var _assign = /*#__PURE__*/function () {
|
|
402
|
-
var
|
|
402
|
+
var _ref6 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(opt) {
|
|
403
403
|
var _opt$tags3;
|
|
404
|
-
var p, _opt, hash, _yield$ar$dataitem2, id, owner, item, _opt$data2,
|
|
404
|
+
var p, _opt, hash, _yield$ar$dataitem2, id, owner, item, _opt$data2, _ref7, _opt$from, _res$Messages, _res$Spawns, _res$Assignments, data, _tags, from, raw_owner, hashBuffer, msg, _env, res, _iterator2, _step2, v, _iterator3, _step3, _v, __tags, _iterator4, _step4, _v2, _iterator5, _step5, v2;
|
|
405
405
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
406
406
|
while (1) switch (_context2.prev = _context2.next) {
|
|
407
407
|
case 0:
|
|
@@ -457,7 +457,7 @@ var connect = exports.connect = function connect(mem) {
|
|
|
457
457
|
_context2.prev = 21;
|
|
458
458
|
data = (_opt$data2 = _opt.data) !== null && _opt$data2 !== void 0 ? _opt$data2 : "";
|
|
459
459
|
_tags = _opt.tags;
|
|
460
|
-
from = (
|
|
460
|
+
from = (_ref7 = (_opt$from = _opt.from) !== null && _opt$from !== void 0 ? _opt$from : opt.from) !== null && _ref7 !== void 0 ? _ref7 : owner;
|
|
461
461
|
if (!_opt.item) {
|
|
462
462
|
_context2.next = 42;
|
|
463
463
|
break;
|
|
@@ -643,11 +643,11 @@ var connect = exports.connect = function connect(mem) {
|
|
|
643
643
|
}, _callee2, null, [[21, 124], [26, 39], [54, 65, 68, 71], [72, 83, 86, 89], [90, 115, 118, 121], [95, 105, 108, 111]]);
|
|
644
644
|
}));
|
|
645
645
|
return function assign(_x) {
|
|
646
|
-
return
|
|
646
|
+
return _ref6.apply(this, arguments);
|
|
647
647
|
};
|
|
648
648
|
}();
|
|
649
649
|
var message = /*#__PURE__*/function () {
|
|
650
|
-
var
|
|
650
|
+
var _ref8 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(opt) {
|
|
651
651
|
var _opt$item$id, _opt$item, _opt$owner;
|
|
652
652
|
var p, ex, id, owner, item, _opt$tags4, _iterator6, _step6, v, _yield$ar$dataitem3;
|
|
653
653
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
@@ -716,7 +716,7 @@ var connect = exports.connect = function connect(mem) {
|
|
|
716
716
|
}, _callee3);
|
|
717
717
|
}));
|
|
718
718
|
return function message(_x2) {
|
|
719
|
-
return
|
|
719
|
+
return _ref8.apply(this, arguments);
|
|
720
720
|
};
|
|
721
721
|
}();
|
|
722
722
|
return {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
local json = require("json")
|
|
2
|
+
function rollup (id)
|
|
3
|
+
local file = io.open("/rollup/" .. id)
|
|
4
|
+
local data = nil
|
|
5
|
+
if file then data = file:read(file:seek('end')) end
|
|
6
|
+
file:close()
|
|
7
|
+
return data
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
function get (col, doc)
|
|
11
|
+
local file = io.open("/data/" .. col .. "/" .. doc)
|
|
12
|
+
local data = nil
|
|
13
|
+
if file then data = file:read(file:seek('end')) end
|
|
14
|
+
file:close()
|
|
15
|
+
return data
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Handlers.add(
|
|
19
|
+
"Rollup",
|
|
20
|
+
"Rollup",
|
|
21
|
+
function (msg)
|
|
22
|
+
msg.reply({ Data = "committed!" })
|
|
23
|
+
end
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
Handlers.add(
|
|
27
|
+
"Finalize",
|
|
28
|
+
"Finalize",
|
|
29
|
+
function (msg)
|
|
30
|
+
local data = json.decode(rollup(msg.TXID))
|
|
31
|
+
msg.reply({ Data = "finalized!" })
|
|
32
|
+
end
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Handlers.add(
|
|
37
|
+
"Get",
|
|
38
|
+
"Get",
|
|
39
|
+
function (msg)
|
|
40
|
+
msg.reply({ Data = get(msg.col, msg.doc) })
|
|
41
|
+
end
|
|
42
|
+
)
|
|
43
|
+
|
package/cjs/server.js
CHANGED
|
@@ -44,7 +44,9 @@ var Server = /*#__PURE__*/function () {
|
|
|
44
44
|
_ref$log = _ref.log,
|
|
45
45
|
log = _ref$log === void 0 ? false : _ref$log;
|
|
46
46
|
_classCallCheck(this, Server);
|
|
47
|
-
var _connect = (0, _aoconnect.connect)(aoconnect,
|
|
47
|
+
var _connect = (0, _aoconnect.connect)(aoconnect, {
|
|
48
|
+
log: log
|
|
49
|
+
}),
|
|
48
50
|
_ar = _connect.ar,
|
|
49
51
|
message = _connect.message,
|
|
50
52
|
spawn = _connect.spawn,
|
package/cjs/tao.js
CHANGED
|
@@ -72,7 +72,9 @@ var AO = /*#__PURE__*/function (_MAO) {
|
|
|
72
72
|
in_memory: true
|
|
73
73
|
})]);
|
|
74
74
|
_this.in_memory = true;
|
|
75
|
-
var _connect = (0, _aoconnect2.connect)(opt.mem
|
|
75
|
+
var _connect = (0, _aoconnect2.connect)(opt.mem, {
|
|
76
|
+
extensions: opt.extensions
|
|
77
|
+
}),
|
|
76
78
|
modules = _connect.modules,
|
|
77
79
|
results = _connect.results,
|
|
78
80
|
assign = _connect.assign,
|
package/cjs/{kv.js → weavedb.js}
RENAMED
|
@@ -5,10 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports["default"] = void 0;
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var _ramda = require("ramda");
|
|
11
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
8
|
+
var _path = require("path");
|
|
9
|
+
var _fs = require("fs");
|
|
12
10
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
13
11
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
14
12
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
@@ -26,14 +24,28 @@ var CACHE_SZ = 32 * KB;
|
|
|
26
24
|
var CHUNK_SZ = 128 * MB;
|
|
27
25
|
var NOTIFY_SZ = 512 * MB;
|
|
28
26
|
var log = console.log;
|
|
29
|
-
var
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
var rand = Math.floor(Math.random() * 1000000).toString();
|
|
28
|
+
var WeaveDB = exports["default"] = /*#__PURE__*/_createClass(function WeaveDB(ar, dir) {
|
|
29
|
+
var _dir;
|
|
30
|
+
_classCallCheck(this, WeaveDB);
|
|
31
|
+
(_dir = dir) !== null && _dir !== void 0 ? _dir : dir = (0, _path.resolve)(import.meta.dirname, ".db");
|
|
32
|
+
var kv_dir = (0, _path.resolve)(dir, rand);
|
|
33
|
+
var data_dir = (0, _path.resolve)(kv_dir, "data");
|
|
34
|
+
var rollup_dir = (0, _path.resolve)(kv_dir, "rollup");
|
|
35
|
+
for (var _i = 0, _arr = [dir, kv_dir, rollup_dir, data_dir]; _i < _arr.length; _i++) {
|
|
36
|
+
var v = _arr[_i];
|
|
37
|
+
if (!(0, _fs.existsSync)(v)) (0, _fs.mkdirSync)(v);
|
|
38
|
+
}
|
|
39
|
+
this.ext = function (mod, FS) {
|
|
40
|
+
var cache = {
|
|
41
|
+
data: {},
|
|
42
|
+
rollup: {}
|
|
43
|
+
};
|
|
32
44
|
return {
|
|
33
45
|
create: function create(id) {
|
|
34
46
|
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
35
|
-
var
|
|
36
|
-
var properties, node, bytesLength, stream;
|
|
47
|
+
var _data$length;
|
|
48
|
+
var properties, node, data, bytesLength, stream;
|
|
37
49
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
38
50
|
while (1) switch (_context.prev = _context.next) {
|
|
39
51
|
case 0:
|
|
@@ -41,48 +53,13 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
41
53
|
isDevice: false,
|
|
42
54
|
contents: null
|
|
43
55
|
};
|
|
44
|
-
if (!FS.analyzePath("/
|
|
45
|
-
node = FS.createFile("/", "
|
|
56
|
+
if (!FS.analyzePath("/rollup/").exists) FS.mkdir("/rollup/");
|
|
57
|
+
node = FS.createFile("/", "rollup/" + id, properties, true, false); // Set initial parame
|
|
46
58
|
_context.next = 5;
|
|
47
59
|
return ar.data(id);
|
|
48
60
|
case 5:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (_context.t1) {
|
|
52
|
-
_context.next = 9;
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
_context.t1 = _yield$ar$data === void 0;
|
|
56
|
-
case 9:
|
|
57
|
-
if (!_context.t1) {
|
|
58
|
-
_context.next = 13;
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
_context.t3 = void 0;
|
|
62
|
-
_context.next = 14;
|
|
63
|
-
break;
|
|
64
|
-
case 13:
|
|
65
|
-
_context.t3 = _yield$ar$data.length;
|
|
66
|
-
case 14:
|
|
67
|
-
_context.t4 = _yield$ar$data$length = _context.t3;
|
|
68
|
-
_context.t0 = _context.t4 !== null;
|
|
69
|
-
if (!_context.t0) {
|
|
70
|
-
_context.next = 18;
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
_context.t0 = _yield$ar$data$length !== void 0;
|
|
74
|
-
case 18:
|
|
75
|
-
if (!_context.t0) {
|
|
76
|
-
_context.next = 22;
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
_context.t5 = _yield$ar$data$length;
|
|
80
|
-
_context.next = 23;
|
|
81
|
-
break;
|
|
82
|
-
case 22:
|
|
83
|
-
_context.t5 = 0;
|
|
84
|
-
case 23:
|
|
85
|
-
bytesLength = _context.t5;
|
|
61
|
+
data = _context.sent;
|
|
62
|
+
bytesLength = (_data$length = data === null || data === void 0 ? void 0 : data.length) !== null && _data$length !== void 0 ? _data$length : 0;
|
|
86
63
|
node.total_size = Number(bytesLength);
|
|
87
64
|
node.cache = new Uint8Array(0);
|
|
88
65
|
node.position = 0;
|
|
@@ -97,66 +74,141 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
97
74
|
});
|
|
98
75
|
|
|
99
76
|
// Now we have created the file in the emscripten FS, we can open it as a stream
|
|
100
|
-
stream = FS.open("/
|
|
77
|
+
stream = FS.open("/rollup/" + id, "r"); //console.log("JS: Created file: ", id, " fd: ", stream.fd);
|
|
101
78
|
return _context.abrupt("return", stream);
|
|
102
|
-
case
|
|
79
|
+
case 13:
|
|
103
80
|
case "end":
|
|
104
81
|
return _context.stop();
|
|
105
82
|
}
|
|
106
83
|
}, _callee);
|
|
107
84
|
}))();
|
|
108
85
|
},
|
|
109
|
-
|
|
110
|
-
var _this = this;
|
|
86
|
+
createData: function createData(col, doc, val) {
|
|
111
87
|
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
112
|
-
var
|
|
88
|
+
var _data$length2, _data2;
|
|
89
|
+
var properties, node, data, _readFileSync, col_dir, _data, bytesLength, stream;
|
|
113
90
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
114
91
|
while (1) switch (_context2.prev = _context2.next) {
|
|
92
|
+
case 0:
|
|
93
|
+
properties = {
|
|
94
|
+
isDevice: false,
|
|
95
|
+
contents: null
|
|
96
|
+
};
|
|
97
|
+
if (!FS.analyzePath("/data/").exists) FS.mkdir("/data/");
|
|
98
|
+
if (!FS.analyzePath("/data/".concat(col)).exists) FS.mkdir("/data/".concat(col));
|
|
99
|
+
node = FS.createFile("/", "data/".concat(col, "/").concat(doc), properties, true, false); // Set initial parame
|
|
100
|
+
data = val;
|
|
101
|
+
if (!val) {
|
|
102
|
+
col_dir = (0, _path.resolve)(data_dir, col);
|
|
103
|
+
_data = (_readFileSync = (0, _fs.readFileSync)((0, _path.resolve)(col_dir, "".concat(doc, ".json")), "utf8")) !== null && _readFileSync !== void 0 ? _readFileSync : "";
|
|
104
|
+
data = Buffer.from(_data, "utf8");
|
|
105
|
+
}
|
|
106
|
+
bytesLength = (_data$length2 = (_data2 = data) === null || _data2 === void 0 ? void 0 : _data2.length) !== null && _data$length2 !== void 0 ? _data$length2 : 0;
|
|
107
|
+
node.total_size = Number(bytesLength);
|
|
108
|
+
node.cache = new Uint8Array(0);
|
|
109
|
+
node.position = 0;
|
|
110
|
+
|
|
111
|
+
// Add a function that defers querying the file size until it is asked the first time.
|
|
112
|
+
Object.defineProperties(node, {
|
|
113
|
+
usedBytes: {
|
|
114
|
+
get: function get() {
|
|
115
|
+
return bytesLength;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Now we have created the file in the emscripten FS, we can open it as a stream
|
|
121
|
+
stream = FS.open("/data/" + "".concat(col, "/").concat(doc), "r"); //console.log("JS: Created file: ", id, " fd: ", stream.fd);
|
|
122
|
+
return _context2.abrupt("return", stream);
|
|
123
|
+
case 13:
|
|
124
|
+
case "end":
|
|
125
|
+
return _context2.stop();
|
|
126
|
+
}
|
|
127
|
+
}, _callee2);
|
|
128
|
+
}))();
|
|
129
|
+
},
|
|
130
|
+
open: function open(filename, val) {
|
|
131
|
+
var _this = this;
|
|
132
|
+
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
133
|
+
var pathCategory, id, stream, _stream, col, doc, _stream2, _stream3;
|
|
134
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
135
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
115
136
|
case 0:
|
|
116
137
|
pathCategory = filename.split("/")[1];
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
_context2.next = 17;
|
|
138
|
+
if (!(pathCategory === "rollup")) {
|
|
139
|
+
_context3.next = 17;
|
|
120
140
|
break;
|
|
121
141
|
}
|
|
142
|
+
//log("JS: Opening ID: ", id)
|
|
143
|
+
id = filename.split("/")[2];
|
|
122
144
|
if (!FS.analyzePath(filename).exists) {
|
|
123
|
-
|
|
145
|
+
_context3.next = 11;
|
|
124
146
|
break;
|
|
125
147
|
}
|
|
126
148
|
stream = FS.open(filename, "r");
|
|
127
149
|
if (!stream.fd) {
|
|
128
|
-
|
|
150
|
+
_context3.next = 7;
|
|
129
151
|
break;
|
|
130
152
|
}
|
|
131
|
-
return
|
|
153
|
+
return _context3.abrupt("return", stream.fd);
|
|
132
154
|
case 7:
|
|
133
155
|
console.log("JS: File not found: ", filename);
|
|
134
|
-
return
|
|
156
|
+
return _context3.abrupt("return", 0);
|
|
135
157
|
case 11:
|
|
136
|
-
|
|
158
|
+
_context3.next = 13;
|
|
137
159
|
return _this.create(id);
|
|
138
160
|
case 13:
|
|
139
|
-
_stream =
|
|
140
|
-
return
|
|
161
|
+
_stream = _context3.sent;
|
|
162
|
+
return _context3.abrupt("return", _stream.fd);
|
|
141
163
|
case 15:
|
|
142
|
-
|
|
164
|
+
_context3.next = 36;
|
|
143
165
|
break;
|
|
144
166
|
case 17:
|
|
167
|
+
if (!(pathCategory === "data")) {
|
|
168
|
+
_context3.next = 34;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
//log("JS: Opening ID: ", id)
|
|
172
|
+
col = filename.split("/")[2];
|
|
173
|
+
doc = filename.split("/")[3];
|
|
174
|
+
if (!FS.analyzePath(filename).exists) {
|
|
175
|
+
_context3.next = 28;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
_stream2 = FS.open(filename, "r");
|
|
179
|
+
if (!_stream2.fd) {
|
|
180
|
+
_context3.next = 24;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
return _context3.abrupt("return", _stream2.fd);
|
|
184
|
+
case 24:
|
|
185
|
+
console.log("JS: File not found: ", filename);
|
|
186
|
+
return _context3.abrupt("return", 0);
|
|
187
|
+
case 28:
|
|
188
|
+
_context3.next = 30;
|
|
189
|
+
return _this.createData(col, doc, val);
|
|
190
|
+
case 30:
|
|
191
|
+
_stream3 = _context3.sent;
|
|
192
|
+
return _context3.abrupt("return", _stream3.fd);
|
|
193
|
+
case 32:
|
|
194
|
+
_context3.next = 36;
|
|
195
|
+
break;
|
|
196
|
+
case 34:
|
|
145
197
|
console.log("JS: Invalid path category: ", pathCategory);
|
|
146
|
-
return
|
|
147
|
-
case
|
|
198
|
+
return _context3.abrupt("return", 0);
|
|
199
|
+
case 36:
|
|
148
200
|
case "end":
|
|
149
|
-
return
|
|
201
|
+
return _context3.stop();
|
|
150
202
|
}
|
|
151
|
-
},
|
|
203
|
+
}, _callee3);
|
|
152
204
|
}))();
|
|
153
205
|
},
|
|
154
|
-
read: function read(fd, raw_dst_ptr, raw_length) {
|
|
206
|
+
read: function read(fd, raw_dst_ptr, raw_length, val) {
|
|
155
207
|
var _this2 = this;
|
|
156
|
-
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function
|
|
157
|
-
var to_read, dst_ptr, stream, i, bytes_read, chunk_download_sz, to, data, start, end, chunk, response, reader, bytes_until_cache, bytes_until_notify, downloaded_bytes, cache_chunks, _yield$reader$read, done, chunk_bytes, write_length, chunk_to_cache;
|
|
158
|
-
return _regeneratorRuntime().wrap(function
|
|
159
|
-
while (1) switch (
|
|
208
|
+
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
|
|
209
|
+
var to_read, dst_ptr, stream, i, bytes_read, chunk_download_sz, to, data, sp, _readFileSync2, col_dir, _data, json, _iterator, _step, _v, _val, _fd, _col_dir, start, end, chunk, response, reader, bytes_until_cache, bytes_until_notify, downloaded_bytes, cache_chunks, _yield$reader$read, done, chunk_bytes, write_length, chunk_to_cache;
|
|
210
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
211
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
160
212
|
case 0:
|
|
161
213
|
to_read = Number(raw_length);
|
|
162
214
|
dst_ptr = Number(raw_dst_ptr);
|
|
@@ -164,7 +216,6 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
164
216
|
for (i = 0; i < FS.streams.length; i++) {
|
|
165
217
|
if (FS.streams[i].fd === fd) stream = FS.streams[i];
|
|
166
218
|
}
|
|
167
|
-
|
|
168
219
|
// Satisfy what we can with the cache first
|
|
169
220
|
bytes_read = _this2.readFromCache(stream, dst_ptr, to_read);
|
|
170
221
|
stream.position += bytes_read;
|
|
@@ -173,19 +224,80 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
173
224
|
to_read -= bytes_read;
|
|
174
225
|
|
|
175
226
|
// Return if we have satisfied the request
|
|
227
|
+
|
|
228
|
+
//console.log("KV: Satisfied request with cache. Returning...")
|
|
176
229
|
if (!(to_read === 0)) {
|
|
177
|
-
|
|
230
|
+
_context4.next = 11;
|
|
178
231
|
break;
|
|
179
232
|
}
|
|
180
|
-
return
|
|
233
|
+
return _context4.abrupt("return", bytes_read);
|
|
181
234
|
case 11:
|
|
182
|
-
//console.log("
|
|
235
|
+
//console.log("KV: Read from cache: ", bytes_read, " Remaining to read: ", to_read)
|
|
183
236
|
chunk_download_sz = Math.max(to_read, CACHE_SZ);
|
|
184
237
|
to = Math.min(stream.node.total_size, stream.position + chunk_download_sz);
|
|
185
|
-
|
|
238
|
+
data = val;
|
|
239
|
+
if (data) {
|
|
240
|
+
_context4.next = 56;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
sp = stream.path.split("/");
|
|
244
|
+
if (!(sp[1] === "data")) {
|
|
245
|
+
_context4.next = 22;
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
col_dir = (0, _path.resolve)(data_dir, sp[2]);
|
|
249
|
+
_data = (_readFileSync2 = (0, _fs.readFileSync)((0, _path.resolve)(col_dir, "".concat(sp[3], ".json")), "utf8")) !== null && _readFileSync2 !== void 0 ? _readFileSync2 : "";
|
|
250
|
+
data = Buffer.from(_data, "utf8");
|
|
251
|
+
_context4.next = 56;
|
|
252
|
+
break;
|
|
253
|
+
case 22:
|
|
254
|
+
_context4.next = 24;
|
|
186
255
|
return ar.data(stream.node.name);
|
|
187
|
-
case
|
|
188
|
-
data =
|
|
256
|
+
case 24:
|
|
257
|
+
data = _context4.sent;
|
|
258
|
+
_context4.prev = 25;
|
|
259
|
+
json = JSON.parse(Buffer.from(data).toString());
|
|
260
|
+
_iterator = _createForOfIteratorHelper(json.diffs);
|
|
261
|
+
_context4.prev = 28;
|
|
262
|
+
_iterator.s();
|
|
263
|
+
case 30:
|
|
264
|
+
if ((_step = _iterator.n()).done) {
|
|
265
|
+
_context4.next = 43;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
_v = _step.value;
|
|
269
|
+
_val = Buffer.from(JSON.stringify(_v.data));
|
|
270
|
+
_context4.next = 35;
|
|
271
|
+
return _this2.open("/data/".concat(_v.collection, "/").concat(_v.doc), _val);
|
|
272
|
+
case 35:
|
|
273
|
+
_fd = _context4.sent;
|
|
274
|
+
_col_dir = (0, _path.resolve)(data_dir, _v.collection);
|
|
275
|
+
if (!(0, _fs.existsSync)(_col_dir)) (0, _fs.mkdirSync)(_col_dir);
|
|
276
|
+
(0, _fs.writeFileSync)((0, _path.resolve)(_col_dir, "".concat(_v.doc, ".json")), JSON.stringify(_v.data));
|
|
277
|
+
_context4.next = 41;
|
|
278
|
+
return _this2.read(_fd, _fd, _val.length, _val);
|
|
279
|
+
case 41:
|
|
280
|
+
_context4.next = 30;
|
|
281
|
+
break;
|
|
282
|
+
case 43:
|
|
283
|
+
_context4.next = 48;
|
|
284
|
+
break;
|
|
285
|
+
case 45:
|
|
286
|
+
_context4.prev = 45;
|
|
287
|
+
_context4.t0 = _context4["catch"](28);
|
|
288
|
+
_iterator.e(_context4.t0);
|
|
289
|
+
case 48:
|
|
290
|
+
_context4.prev = 48;
|
|
291
|
+
_iterator.f();
|
|
292
|
+
return _context4.finish(48);
|
|
293
|
+
case 51:
|
|
294
|
+
_context4.next = 56;
|
|
295
|
+
break;
|
|
296
|
+
case 53:
|
|
297
|
+
_context4.prev = 53;
|
|
298
|
+
_context4.t1 = _context4["catch"](25);
|
|
299
|
+
log(_context4.t1);
|
|
300
|
+
case 56:
|
|
189
301
|
// Extract the Range header to determine the start and end of the requested chunk
|
|
190
302
|
start = 0;
|
|
191
303
|
end = data.length; // Create a ReadableStream for the requested chunk
|
|
@@ -205,24 +317,24 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
205
317
|
bytes_until_notify = NOTIFY_SZ;
|
|
206
318
|
downloaded_bytes = 0;
|
|
207
319
|
cache_chunks = [];
|
|
208
|
-
|
|
209
|
-
case
|
|
320
|
+
_context4.prev = 65;
|
|
321
|
+
case 66:
|
|
210
322
|
if (!true) {
|
|
211
|
-
|
|
323
|
+
_context4.next = 84;
|
|
212
324
|
break;
|
|
213
325
|
}
|
|
214
|
-
|
|
326
|
+
_context4.next = 69;
|
|
215
327
|
return reader.read();
|
|
216
|
-
case
|
|
217
|
-
_yield$reader$read =
|
|
328
|
+
case 69:
|
|
329
|
+
_yield$reader$read = _context4.sent;
|
|
218
330
|
done = _yield$reader$read.done;
|
|
219
331
|
chunk_bytes = _yield$reader$read.value;
|
|
220
332
|
if (!done) {
|
|
221
|
-
|
|
333
|
+
_context4.next = 74;
|
|
222
334
|
break;
|
|
223
335
|
}
|
|
224
|
-
return
|
|
225
|
-
case
|
|
336
|
+
return _context4.abrupt("break", 84);
|
|
337
|
+
case 74:
|
|
226
338
|
// Update the number of downloaded bytes to be _all_, not just the write length
|
|
227
339
|
downloaded_bytes += chunk_bytes.length;
|
|
228
340
|
bytes_until_cache -= chunk_bytes.length;
|
|
@@ -231,7 +343,7 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
231
343
|
// Write bytes from the chunk and update the pointer if necessary
|
|
232
344
|
write_length = Math.min(chunk_bytes.length, to_read);
|
|
233
345
|
if (write_length > 0) {
|
|
234
|
-
//console.log("
|
|
346
|
+
//console.log("KV: Writing: ", write_length, " bytes to: ", dst_ptr)
|
|
235
347
|
mod.HEAP8.set(chunk_bytes.subarray(0, write_length), dst_ptr);
|
|
236
348
|
dst_ptr += write_length;
|
|
237
349
|
bytes_read += write_length;
|
|
@@ -240,45 +352,45 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
240
352
|
}
|
|
241
353
|
if (to_read == 0) {
|
|
242
354
|
// Add excess bytes to our cache
|
|
243
|
-
chunk_to_cache = chunk_bytes.subarray(write_length); //console.log("
|
|
355
|
+
chunk_to_cache = chunk_bytes.subarray(write_length); //console.log("KV: Cacheing excess: ", chunk_to_cache.length)
|
|
244
356
|
cache_chunks.push(chunk_to_cache);
|
|
245
357
|
}
|
|
246
358
|
if (bytes_until_cache <= 0) {
|
|
247
|
-
console.log("
|
|
359
|
+
console.log("KV: Chunk size reached. Compressing cache...");
|
|
248
360
|
stream.node.cache = _this2.addChunksToCache(stream.node.cache, cache_chunks);
|
|
249
361
|
cache_chunks = [];
|
|
250
362
|
bytes_until_cache = CHUNK_SZ;
|
|
251
363
|
}
|
|
252
364
|
if (bytes_until_notify <= 0) {
|
|
253
|
-
console.log("
|
|
365
|
+
console.log("KV: Downloaded: ", downloaded_bytes / stream.node.total_size * 100, "%");
|
|
254
366
|
bytes_until_notify = NOTIFY_SZ;
|
|
255
367
|
}
|
|
256
|
-
|
|
368
|
+
_context4.next = 66;
|
|
257
369
|
break;
|
|
258
|
-
case
|
|
259
|
-
|
|
370
|
+
case 84:
|
|
371
|
+
_context4.next = 89;
|
|
260
372
|
break;
|
|
261
|
-
case
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
console.error("
|
|
265
|
-
case
|
|
266
|
-
|
|
373
|
+
case 86:
|
|
374
|
+
_context4.prev = 86;
|
|
375
|
+
_context4.t2 = _context4["catch"](65);
|
|
376
|
+
console.error("KV: Error reading the stream: ", _context4.t2);
|
|
377
|
+
case 89:
|
|
378
|
+
_context4.prev = 89;
|
|
267
379
|
reader.releaseLock();
|
|
268
|
-
return
|
|
269
|
-
case
|
|
380
|
+
return _context4.finish(89);
|
|
381
|
+
case 92:
|
|
270
382
|
// If we have no cache, or we have not satisfied the full request, we need to download the rest
|
|
271
383
|
// Rebuild the cache from the new cache chunks
|
|
272
384
|
stream.node.cache = _this2.addChunksToCache(stream.node.cache, cache_chunks);
|
|
273
385
|
|
|
274
386
|
// Update the last read position
|
|
275
387
|
stream.lastReadPosition = stream.position;
|
|
276
|
-
return
|
|
277
|
-
case
|
|
388
|
+
return _context4.abrupt("return", bytes_read);
|
|
389
|
+
case 95:
|
|
278
390
|
case "end":
|
|
279
|
-
return
|
|
391
|
+
return _context4.stop();
|
|
280
392
|
}
|
|
281
|
-
},
|
|
393
|
+
}, _callee4, null, [[25, 53], [28, 45, 48, 51], [65, 86, 89, 92]]);
|
|
282
394
|
}))();
|
|
283
395
|
},
|
|
284
396
|
close: function close(fd) {
|
|
@@ -291,7 +403,7 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
291
403
|
readFromCache: function readFromCache(stream, dst_ptr, length) {
|
|
292
404
|
// Check if the cache has been invalidated by a seek
|
|
293
405
|
if (stream.lastReadPosition !== stream.position) {
|
|
294
|
-
//console.log("
|
|
406
|
+
//console.log("KV: Invalidating cache for fd: ", stream.fd, " Current pos: ", stream.position, " Last read pos: ", stream.lastReadPosition)
|
|
295
407
|
stream.node.cache = new Uint8Array(0);
|
|
296
408
|
return 0;
|
|
297
409
|
}
|
|
@@ -313,20 +425,20 @@ var KV = exports["default"] = /*#__PURE__*/_createClass(function KV(ar) {
|
|
|
313
425
|
new_cache.set(old_cache, 0);
|
|
314
426
|
// Load the cache chunks into the new cache
|
|
315
427
|
var current_offset = old_cache.length;
|
|
316
|
-
var
|
|
317
|
-
|
|
428
|
+
var _iterator2 = _createForOfIteratorHelper(chunks),
|
|
429
|
+
_step2;
|
|
318
430
|
try {
|
|
319
|
-
for (
|
|
320
|
-
var chunk =
|
|
431
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
432
|
+
var chunk = _step2.value;
|
|
321
433
|
if (current_offset < new_cache_length) {
|
|
322
434
|
new_cache.set(chunk.subarray(0, new_cache_length - current_offset), current_offset);
|
|
323
435
|
current_offset += chunk.length;
|
|
324
436
|
}
|
|
325
437
|
}
|
|
326
438
|
} catch (err) {
|
|
327
|
-
|
|
439
|
+
_iterator2.e(err);
|
|
328
440
|
} finally {
|
|
329
|
-
|
|
441
|
+
_iterator2.f();
|
|
330
442
|
}
|
|
331
443
|
return new_cache;
|
|
332
444
|
}
|
package/cjs/weavedrive.js
CHANGED
|
@@ -31,7 +31,7 @@ var NOTIFY_SZ = 512 * MB;
|
|
|
31
31
|
var log = console.log;
|
|
32
32
|
var WeaveDrive = exports["default"] = /*#__PURE__*/_createClass(function WeaveDrive(ar) {
|
|
33
33
|
_classCallCheck(this, WeaveDrive);
|
|
34
|
-
this.
|
|
34
|
+
this.ext = function (mod, FS) {
|
|
35
35
|
return {
|
|
36
36
|
reset: function reset(fd) {
|
|
37
37
|
//console.log("WeaveDrive: Resetting fd: ", fd)
|
|
@@ -49,7 +49,7 @@ var WeaveDrive = exports["default"] = /*#__PURE__*/_createClass(function WeaveDr
|
|
|
49
49
|
properties = {
|
|
50
50
|
isDevice: false,
|
|
51
51
|
contents: null
|
|
52
|
-
};
|
|
52
|
+
}; //console.log("WeaveDrive: Arweave ID is not admissable! ", id)
|
|
53
53
|
_context.next = 3;
|
|
54
54
|
return _this.checkAdmissible(id);
|
|
55
55
|
case 3:
|
|
@@ -98,7 +98,7 @@ var WeaveDrive = exports["default"] = /*#__PURE__*/_createClass(function WeaveDr
|
|
|
98
98
|
},
|
|
99
99
|
createBlockHeader: function createBlockHeader(id) {
|
|
100
100
|
return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
101
|
-
var result, block,
|
|
101
|
+
var result, block, node, stream;
|
|
102
102
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
103
103
|
while (1) switch (_context2.prev = _context2.next) {
|
|
104
104
|
case 0:
|
|
@@ -117,11 +117,10 @@ var WeaveDrive = exports["default"] = /*#__PURE__*/_createClass(function WeaveDr
|
|
|
117
117
|
});
|
|
118
118
|
}
|
|
119
119
|
} catch (e) {}
|
|
120
|
-
bytesLength = result.length;
|
|
121
120
|
node = FS.createDataFile("/", "block/" + id, Buffer.from(result, "utf-8"), true, false);
|
|
122
121
|
stream = FS.open("/block/" + id, "r");
|
|
123
122
|
return _context2.abrupt("return", stream);
|
|
124
|
-
case
|
|
123
|
+
case 5:
|
|
125
124
|
case "end":
|
|
126
125
|
return _context2.stop();
|
|
127
126
|
}
|
|
@@ -345,6 +344,8 @@ var WeaveDrive = exports["default"] = /*#__PURE__*/_createClass(function WeaveDr
|
|
|
345
344
|
to_read -= bytes_read;
|
|
346
345
|
|
|
347
346
|
// Return if we have satisfied the request
|
|
347
|
+
|
|
348
|
+
//console.log("WeaveDrive: Satisfied request with cache. Returning...")
|
|
348
349
|
if (!(to_read === 0)) {
|
|
349
350
|
_context6.next = 17;
|
|
350
351
|
break;
|
package/esm/aoconnect.js
CHANGED
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
} from "./utils.js"
|
|
17
17
|
import ArMem from "./armem.js"
|
|
18
18
|
import weavedrive from "./weavedrive.js"
|
|
19
|
-
import kv from "./kv.js"
|
|
20
19
|
import AoLoader from "@permaweb/ao-loader"
|
|
21
20
|
import { readFileSync } from "fs"
|
|
22
21
|
import { resolve } from "path"
|
|
@@ -24,7 +23,7 @@ import { scheduler, mu, su, cu, acc } from "./test.js"
|
|
|
24
23
|
import { is, clone, fromPairs, map, mergeLeft, isNil } from "ramda"
|
|
25
24
|
import AR from "./tar.js"
|
|
26
25
|
|
|
27
|
-
export const connect = (mem, log = false) => {
|
|
26
|
+
export const connect = (mem, { log = false, extensions = {} }) => {
|
|
28
27
|
const isMem = mem?.__type__ === "mem"
|
|
29
28
|
if (!isMem) {
|
|
30
29
|
let args = {}
|
|
@@ -35,8 +34,8 @@ export const connect = (mem, log = false) => {
|
|
|
35
34
|
mem = new ArMem(args)
|
|
36
35
|
}
|
|
37
36
|
const ar = new AR({ mem, log })
|
|
38
|
-
const
|
|
39
|
-
|
|
37
|
+
for (const k in extensions) extensions[k] = new extensions[k](ar).ext
|
|
38
|
+
extensions.WeaveDrive = new weavedrive(ar).ext
|
|
40
39
|
|
|
41
40
|
const transform = input => {
|
|
42
41
|
const output = { Tags: [] }
|
|
@@ -152,10 +151,9 @@ export const connect = (mem, log = false) => {
|
|
|
152
151
|
await ar.postItems(item, su.jwk)
|
|
153
152
|
const now = Date.now
|
|
154
153
|
const t = tags(opt.tags)
|
|
155
|
-
const wd = t.Extension === "KV" ? KV : WeaveDrive
|
|
156
154
|
const handle = await AoLoader(wasm, {
|
|
157
155
|
format,
|
|
158
|
-
WeaveDrive:
|
|
156
|
+
WeaveDrive: extensions[t.Extension],
|
|
159
157
|
spawn: item,
|
|
160
158
|
module: mem.txs[mod],
|
|
161
159
|
blockHeight: "100",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
local json = require("json")
|
|
2
|
+
function rollup (id)
|
|
3
|
+
local file = io.open("/rollup/" .. id)
|
|
4
|
+
local data = nil
|
|
5
|
+
if file then data = file:read(file:seek('end')) end
|
|
6
|
+
file:close()
|
|
7
|
+
return data
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
function get (col, doc)
|
|
11
|
+
local file = io.open("/data/" .. col .. "/" .. doc)
|
|
12
|
+
local data = nil
|
|
13
|
+
if file then data = file:read(file:seek('end')) end
|
|
14
|
+
file:close()
|
|
15
|
+
return data
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Handlers.add(
|
|
19
|
+
"Rollup",
|
|
20
|
+
"Rollup",
|
|
21
|
+
function (msg)
|
|
22
|
+
msg.reply({ Data = "committed!" })
|
|
23
|
+
end
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
Handlers.add(
|
|
27
|
+
"Finalize",
|
|
28
|
+
"Finalize",
|
|
29
|
+
function (msg)
|
|
30
|
+
local data = json.decode(rollup(msg.TXID))
|
|
31
|
+
msg.reply({ Data = "finalized!" })
|
|
32
|
+
end
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Handlers.add(
|
|
37
|
+
"Get",
|
|
38
|
+
"Get",
|
|
39
|
+
function (msg)
|
|
40
|
+
msg.reply({ Data = get(msg.col, msg.doc) })
|
|
41
|
+
end
|
|
42
|
+
)
|
|
43
|
+
|
package/esm/server.js
CHANGED
package/esm/tao.js
CHANGED
package/esm/{kv.js → weavedb.js}
RENAMED
|
@@ -1,46 +1,89 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { map } from "ramda"
|
|
4
|
-
|
|
1
|
+
import { resolve } from "path"
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"
|
|
5
3
|
const KB = 1024
|
|
6
4
|
const MB = KB * 1024
|
|
7
5
|
const CACHE_SZ = 32 * KB
|
|
8
6
|
const CHUNK_SZ = 128 * MB
|
|
9
7
|
const NOTIFY_SZ = 512 * MB
|
|
10
8
|
const log = console.log
|
|
9
|
+
const rand = Math.floor(Math.random() * 1000000).toString()
|
|
11
10
|
|
|
12
|
-
export default class
|
|
13
|
-
constructor(ar) {
|
|
14
|
-
|
|
11
|
+
export default class WeaveDB {
|
|
12
|
+
constructor(ar, dir) {
|
|
13
|
+
dir ??= resolve(import.meta.dirname, ".db")
|
|
14
|
+
const kv_dir = resolve(dir, rand)
|
|
15
|
+
const data_dir = resolve(kv_dir, "data")
|
|
16
|
+
const rollup_dir = resolve(kv_dir, "rollup")
|
|
17
|
+
for (const v of [dir, kv_dir, rollup_dir, data_dir]) {
|
|
18
|
+
if (!existsSync(v)) mkdirSync(v)
|
|
19
|
+
}
|
|
20
|
+
this.ext = (mod, FS) => {
|
|
21
|
+
let cache = { data: {}, rollup: {} }
|
|
15
22
|
return {
|
|
16
23
|
async create(id) {
|
|
24
|
+
let properties = { isDevice: false, contents: null }
|
|
25
|
+
if (!FS.analyzePath("/rollup/").exists) FS.mkdir("/rollup/")
|
|
26
|
+
let node = FS.createFile("/", "rollup/" + id, properties, true, false)
|
|
27
|
+
|
|
28
|
+
// Set initial parame
|
|
29
|
+
let data = await ar.data(id)
|
|
30
|
+
const bytesLength = data?.length ?? 0
|
|
31
|
+
node.total_size = Number(bytesLength)
|
|
32
|
+
node.cache = new Uint8Array(0)
|
|
33
|
+
node.position = 0
|
|
34
|
+
|
|
35
|
+
// Add a function that defers querying the file size until it is asked the first time.
|
|
36
|
+
Object.defineProperties(node, {
|
|
37
|
+
usedBytes: { get: () => bytesLength },
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// Now we have created the file in the emscripten FS, we can open it as a stream
|
|
41
|
+
let stream = FS.open("/rollup/" + id, "r")
|
|
42
|
+
|
|
43
|
+
//console.log("JS: Created file: ", id, " fd: ", stream.fd);
|
|
44
|
+
return stream
|
|
45
|
+
},
|
|
46
|
+
async createData(col, doc, val) {
|
|
17
47
|
let properties = { isDevice: false, contents: null }
|
|
18
48
|
if (!FS.analyzePath("/data/").exists) FS.mkdir("/data/")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
49
|
+
if (!FS.analyzePath(`/data/${col}`).exists) FS.mkdir(`/data/${col}`)
|
|
50
|
+
let node = FS.createFile(
|
|
51
|
+
"/",
|
|
52
|
+
`data/${col}/${doc}`,
|
|
53
|
+
properties,
|
|
54
|
+
true,
|
|
55
|
+
false,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
// Set initial parame
|
|
59
|
+
let data = val
|
|
60
|
+
if (!val) {
|
|
61
|
+
const col_dir = resolve(data_dir, col)
|
|
62
|
+
const _data =
|
|
63
|
+
readFileSync(resolve(col_dir, `${doc}.json`), "utf8") ?? ""
|
|
64
|
+
data = Buffer.from(_data, "utf8")
|
|
65
|
+
}
|
|
66
|
+
const bytesLength = data?.length ?? 0
|
|
22
67
|
node.total_size = Number(bytesLength)
|
|
23
68
|
node.cache = new Uint8Array(0)
|
|
24
69
|
node.position = 0
|
|
25
70
|
|
|
26
71
|
// Add a function that defers querying the file size until it is asked the first time.
|
|
27
72
|
Object.defineProperties(node, {
|
|
28
|
-
usedBytes: {
|
|
29
|
-
get: () => bytesLength,
|
|
30
|
-
},
|
|
73
|
+
usedBytes: { get: () => bytesLength },
|
|
31
74
|
})
|
|
32
75
|
|
|
33
76
|
// Now we have created the file in the emscripten FS, we can open it as a stream
|
|
34
|
-
let stream = FS.open("/data/" +
|
|
77
|
+
let stream = FS.open("/data/" + `${col}/${doc}`, "r")
|
|
35
78
|
|
|
36
79
|
//console.log("JS: Created file: ", id, " fd: ", stream.fd);
|
|
37
80
|
return stream
|
|
38
81
|
},
|
|
39
|
-
async open(filename) {
|
|
82
|
+
async open(filename, val) {
|
|
40
83
|
const pathCategory = filename.split("/")[1]
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
84
|
+
if (pathCategory === "rollup") {
|
|
85
|
+
//log("JS: Opening ID: ", id)
|
|
86
|
+
const id = filename.split("/")[2]
|
|
44
87
|
if (FS.analyzePath(filename).exists) {
|
|
45
88
|
let stream = FS.open(filename, "r")
|
|
46
89
|
if (stream.fd) return stream.fd
|
|
@@ -52,19 +95,33 @@ export default class KV {
|
|
|
52
95
|
//console.log("JS: Open => Created file: ", id, " fd: ", stream.fd);
|
|
53
96
|
return stream.fd
|
|
54
97
|
}
|
|
98
|
+
} else if (pathCategory === "data") {
|
|
99
|
+
//log("JS: Opening ID: ", id)
|
|
100
|
+
const col = filename.split("/")[2]
|
|
101
|
+
const doc = filename.split("/")[3]
|
|
102
|
+
if (FS.analyzePath(filename).exists) {
|
|
103
|
+
let stream = FS.open(filename, "r")
|
|
104
|
+
if (stream.fd) return stream.fd
|
|
105
|
+
console.log("JS: File not found: ", filename)
|
|
106
|
+
return 0
|
|
107
|
+
} else {
|
|
108
|
+
//console.log("JS: Open => Creating file: ", id);
|
|
109
|
+
const stream = await this.createData(col, doc, val)
|
|
110
|
+
//console.log("JS: Open => Created file: ", id, " fd: ", stream.fd);
|
|
111
|
+
return stream.fd
|
|
112
|
+
}
|
|
55
113
|
} else {
|
|
56
114
|
console.log("JS: Invalid path category: ", pathCategory)
|
|
57
115
|
return 0
|
|
58
116
|
}
|
|
59
117
|
},
|
|
60
|
-
async read(fd, raw_dst_ptr, raw_length) {
|
|
118
|
+
async read(fd, raw_dst_ptr, raw_length, val) {
|
|
61
119
|
let to_read = Number(raw_length)
|
|
62
120
|
let dst_ptr = Number(raw_dst_ptr)
|
|
63
121
|
let stream = 0
|
|
64
122
|
for (let i = 0; i < FS.streams.length; i++) {
|
|
65
123
|
if (FS.streams[i].fd === fd) stream = FS.streams[i]
|
|
66
124
|
}
|
|
67
|
-
|
|
68
125
|
// Satisfy what we can with the cache first
|
|
69
126
|
let bytes_read = this.readFromCache(stream, dst_ptr, to_read)
|
|
70
127
|
stream.position += bytes_read
|
|
@@ -73,22 +130,51 @@ export default class KV {
|
|
|
73
130
|
to_read -= bytes_read
|
|
74
131
|
|
|
75
132
|
// Return if we have satisfied the request
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
//console.log("
|
|
133
|
+
|
|
134
|
+
//console.log("KV: Satisfied request with cache. Returning...")
|
|
135
|
+
if (to_read === 0) return bytes_read
|
|
136
|
+
|
|
137
|
+
//console.log("KV: Read from cache: ", bytes_read, " Remaining to read: ", to_read)
|
|
81
138
|
|
|
82
139
|
const chunk_download_sz = Math.max(to_read, CACHE_SZ)
|
|
83
140
|
const to = Math.min(
|
|
84
141
|
stream.node.total_size,
|
|
85
142
|
stream.position + chunk_download_sz,
|
|
86
143
|
)
|
|
87
|
-
|
|
144
|
+
let data = val
|
|
145
|
+
if (!data) {
|
|
146
|
+
const sp = stream.path.split("/")
|
|
147
|
+
if (sp[1] === "data") {
|
|
148
|
+
const col_dir = resolve(data_dir, sp[2])
|
|
149
|
+
const _data =
|
|
150
|
+
readFileSync(resolve(col_dir, `${sp[3]}.json`), "utf8") ?? ""
|
|
151
|
+
data = Buffer.from(_data, "utf8")
|
|
152
|
+
} else {
|
|
153
|
+
data = await ar.data(stream.node.name)
|
|
154
|
+
try {
|
|
155
|
+
const json = JSON.parse(Buffer.from(data).toString())
|
|
156
|
+
for (const v of json.diffs) {
|
|
157
|
+
const val = Buffer.from(JSON.stringify(v.data))
|
|
158
|
+
const _fd = await this.open(
|
|
159
|
+
`/data/${v.collection}/${v.doc}`,
|
|
160
|
+
val,
|
|
161
|
+
)
|
|
162
|
+
const col_dir = resolve(data_dir, v.collection)
|
|
163
|
+
if (!existsSync(col_dir)) mkdirSync(col_dir)
|
|
164
|
+
writeFileSync(
|
|
165
|
+
resolve(col_dir, `${v.doc}.json`),
|
|
166
|
+
JSON.stringify(v.data),
|
|
167
|
+
)
|
|
168
|
+
await this.read(_fd, _fd, val.length, val)
|
|
169
|
+
}
|
|
170
|
+
} catch (e) {
|
|
171
|
+
log(e)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
88
175
|
// Extract the Range header to determine the start and end of the requested chunk
|
|
89
176
|
const start = 0
|
|
90
177
|
const end = data.length
|
|
91
|
-
|
|
92
178
|
// Create a ReadableStream for the requested chunk
|
|
93
179
|
const chunk = data.subarray(start, end)
|
|
94
180
|
const response = new Response(
|
|
@@ -120,7 +206,7 @@ export default class KV {
|
|
|
120
206
|
// Write bytes from the chunk and update the pointer if necessary
|
|
121
207
|
const write_length = Math.min(chunk_bytes.length, to_read)
|
|
122
208
|
if (write_length > 0) {
|
|
123
|
-
//console.log("
|
|
209
|
+
//console.log("KV: Writing: ", write_length, " bytes to: ", dst_ptr)
|
|
124
210
|
mod.HEAP8.set(chunk_bytes.subarray(0, write_length), dst_ptr)
|
|
125
211
|
dst_ptr += write_length
|
|
126
212
|
bytes_read += write_length
|
|
@@ -131,14 +217,11 @@ export default class KV {
|
|
|
131
217
|
if (to_read == 0) {
|
|
132
218
|
// Add excess bytes to our cache
|
|
133
219
|
const chunk_to_cache = chunk_bytes.subarray(write_length)
|
|
134
|
-
//console.log("
|
|
220
|
+
//console.log("KV: Cacheing excess: ", chunk_to_cache.length)
|
|
135
221
|
cache_chunks.push(chunk_to_cache)
|
|
136
222
|
}
|
|
137
|
-
|
|
138
223
|
if (bytes_until_cache <= 0) {
|
|
139
|
-
console.log(
|
|
140
|
-
"WeaveDrive: Chunk size reached. Compressing cache...",
|
|
141
|
-
)
|
|
224
|
+
console.log("KV: Chunk size reached. Compressing cache...")
|
|
142
225
|
stream.node.cache = this.addChunksToCache(
|
|
143
226
|
stream.node.cache,
|
|
144
227
|
cache_chunks,
|
|
@@ -149,7 +232,7 @@ export default class KV {
|
|
|
149
232
|
|
|
150
233
|
if (bytes_until_notify <= 0) {
|
|
151
234
|
console.log(
|
|
152
|
-
"
|
|
235
|
+
"KV: Downloaded: ",
|
|
153
236
|
(downloaded_bytes / stream.node.total_size) * 100,
|
|
154
237
|
"%",
|
|
155
238
|
)
|
|
@@ -157,7 +240,7 @@ export default class KV {
|
|
|
157
240
|
}
|
|
158
241
|
}
|
|
159
242
|
} catch (error) {
|
|
160
|
-
console.error("
|
|
243
|
+
console.error("KV: Error reading the stream: ", error)
|
|
161
244
|
} finally {
|
|
162
245
|
reader.releaseLock()
|
|
163
246
|
}
|
|
@@ -183,7 +266,7 @@ export default class KV {
|
|
|
183
266
|
readFromCache(stream, dst_ptr, length) {
|
|
184
267
|
// Check if the cache has been invalidated by a seek
|
|
185
268
|
if (stream.lastReadPosition !== stream.position) {
|
|
186
|
-
//console.log("
|
|
269
|
+
//console.log("KV: Invalidating cache for fd: ", stream.fd, " Current pos: ", stream.position, " Last read pos: ", stream.lastReadPosition)
|
|
187
270
|
stream.node.cache = new Uint8Array(0)
|
|
188
271
|
return 0
|
|
189
272
|
}
|
package/esm/weavedrive.js
CHANGED
|
@@ -7,7 +7,7 @@ const log = console.log
|
|
|
7
7
|
|
|
8
8
|
export default class WeaveDrive {
|
|
9
9
|
constructor(ar) {
|
|
10
|
-
this.
|
|
10
|
+
this.ext = (mod, FS) => {
|
|
11
11
|
return {
|
|
12
12
|
reset(fd) {
|
|
13
13
|
//console.log("WeaveDrive: Resetting fd: ", fd)
|
|
@@ -18,10 +18,8 @@ export default class WeaveDrive {
|
|
|
18
18
|
async create(id) {
|
|
19
19
|
var properties = { isDevice: false, contents: null }
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return 0
|
|
24
|
-
}
|
|
21
|
+
//console.log("WeaveDrive: Arweave ID is not admissable! ", id)
|
|
22
|
+
if (!(await this.checkAdmissible(id))) return 0
|
|
25
23
|
|
|
26
24
|
// Create the file in the emscripten FS
|
|
27
25
|
|
|
@@ -42,11 +40,7 @@ export default class WeaveDrive {
|
|
|
42
40
|
|
|
43
41
|
// Add a function that defers querying the file size until it is asked the first time.
|
|
44
42
|
Object.defineProperties(node, {
|
|
45
|
-
usedBytes: {
|
|
46
|
-
get: function () {
|
|
47
|
-
return bytesLength
|
|
48
|
-
},
|
|
49
|
-
},
|
|
43
|
+
usedBytes: { get: () => bytesLength },
|
|
50
44
|
})
|
|
51
45
|
|
|
52
46
|
// Now we have created the file in the emscripten FS, we can open it as a stream
|
|
@@ -72,8 +66,6 @@ export default class WeaveDrive {
|
|
|
72
66
|
}
|
|
73
67
|
} catch (e) {}
|
|
74
68
|
|
|
75
|
-
var bytesLength = result.length
|
|
76
|
-
|
|
77
69
|
var node = FS.createDataFile(
|
|
78
70
|
"/",
|
|
79
71
|
"block/" + id,
|
|
@@ -220,10 +212,10 @@ export default class WeaveDrive {
|
|
|
220
212
|
to_read -= bytes_read
|
|
221
213
|
|
|
222
214
|
// Return if we have satisfied the request
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
215
|
+
|
|
216
|
+
//console.log("WeaveDrive: Satisfied request with cache. Returning...")
|
|
217
|
+
if (to_read === 0) return bytes_read
|
|
218
|
+
|
|
227
219
|
//console.log("WeaveDrive: Read from cache: ", bytes_read, " Remaining to read: ", to_read)
|
|
228
220
|
|
|
229
221
|
const chunk_download_sz = Math.max(to_read, CACHE_SZ)
|