Set: TypeError: Invalid attempt to spread non-iterable instance
Closed this issue · 15 comments
I'm using Babel 7, maybe there is an incompatibility with the polyfills provided by low.js?
TypeError: Invalid attempt to spread non-iterable instance
at _nonIterableSpread (/home/mha/neo/DEVICE/node_modules/@babel/runtime/helpers/nonIterableSpread.js:2)
at _toConsumableArray (/home/mha/neo/DEVICE/node_modules/@babel/runtime/helpers/toConsumableArray.js:8)
at _send (/home/mha/neo/DEVICE/node_modules/one/lib/message-bus.js:68) strict tailcall
at _callee2$ (/home/mha/neo/DEVICE/node_modules/one/lib/instance.js:73) strict
at tryCatch (/home/mha/neo/node_modules/regenerator-runtime/runtime.js:62) strict
at invoke (/home/mha/neo/node_modules/regenerator-runtime/runtime.js:288) strict tailcall
at asyncGeneratorStep (/home/mha/neo/DEVICE/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3)
at _next (/home/mha/neo/DEVICE/node_modules/@babel/runtime/helpers/asyncToGenerator.js:25)
Code in one/lib/message-bus.js
produced by Babel 7:
var typeHandler = handlers.get(type);
if (typeHandler instanceof Set) {
callbacks.push.apply(callbacks, (0, _toConsumableArray2.default)(typeHandler.values()));
}
Let's follow what happens down in _toConsumableArray2
and below in the Babel helpers. Code in @babel/runtime/helpers/toConsumableArray.js:8
:
var arrayWithoutHoles = require("./arrayWithoutHoles");
var iterableToArray = require("./iterableToArray");
var nonIterableSpread = require("./nonIterableSpread");
function _toConsumableArray(arr) {
return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
}
module.exports = _toConsumableArray;
So that ends up failing in iterableToArray
, because the final call to nonIterableSpread()
has only a single active line of code, which is the throw
instruction for the error.
Code in @babel/runtime/helpers/iterableToArray.js
that should have worked but failed:
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
module.exports = _iterableToArray;
PS: I'm a little stubborn with Babel 7, vs. the Babel 6 currently used by lowsync
(or even TS), because... what else would one use in almost 2019? It was a major upgrade awaited for years, should I really optimize anything for Babel 6 at this point? No :-)
I tried it with a Set
object in the low.js REPL.
According to the Babel 7 helper code above one of the following two conditions would have to work:
Either
Symbol.iterator in Object(iterator)
or
Object.prototype.toString.call(iterator) === "[object Arguments]"
When I use mySetObject.values()
as the iterator, the first one produces false
, the second one produces [object Object]
.
In node.js, by the way, the first one is true
, the second one is [object Set Iterator]
(but node.js has a native Set
so the name expected by Babel probably comes from the polyfill in core.js they expect). I think the first condition should already work.
NEW ATTEMPT: Same Babel and Babel config as lowsync uses.
Babel version taken from here: https://github.com/neonious/lowsync/blob/master/package.json#L28
Babel configuration taken from here: https://github.com/neonious/lowsync/blob/master/src/commands/commands/sync/synchronize/syncFile.ts#L69 (I added "babel-plugin-transform-flow-strip-types": "^6.22.0"
)
Result:
mha@mint-virtual-machine ~/neo/DEVICE $ ~/lowjs-linux-x86_64-20190102/bin/low index.js
START
Logger started. info logger
TypeError: undefined not callable (property [Symbol wellknown '?Symbol.iterator?'] of [object Object])
at [anon] (deps/duktape/src-low/duktape.c:64945) internal
at informSubscribers (/home/mha/neo/DEVICE/node_modules/one.core/lib/version-map-updater.js:314) strict
at _callee$ (/home/mha/neo/DEVICE/node_modules/one.core/lib/version-map-updater.js:90) strict
at tryCatch (lib:init:998) strict
at invoke (lib:init:1195) strict tailcall
at step (/home/mha/neo/DEVICE/node_modules/one.core/lib/version-map-updater.js:273) strict
at [anon] (/home/mha/neo/DEVICE/node_modules/one.core/lib/version-map-updater.js:280) strict
...
Line 314 in version-map-updater.js is the for
loop statement in this function:
function informSubscribers(o) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = subscriptions.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _step$value = _slicedToArray(_step.value, 2),
fn = _step$value[0],
hashes = _step$value[1];
if (hashes === undefined || hashes.has(o.idHash)) {
fn(o);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
The original function before Babel-transform is
function informSubscribers (o) {
// subscriptions is an ES 2015 Map object
for (const [fn, hashes] of subscriptions.entries()) {
if (hashes === undefined || hashes.has(o.idHash)) {
fn(o);
}
}
}
So iterator issues again.
Is this urgent or are you having progress with your project even without this (maybe with workarounds?) This is on our road map but other things seem more important right now.
Well, we have quite a lot of Set
and Map
objects and iterations...
OK, I will fix things this week. Right now I do not know where to start however... Can you give a complete project, which I can fix? You know my email address.
Just the code I wrote? Any iteration over a Map
.
Use the transpiled version of this (Babel REPL):
const m = new Map([['string','sträng'],['strüng','ströng']]);
for (const [s1, s2] of m.entries()) {
console.log(s1, s2);
}
For whatever reason I cannot use the URL that includes the code, every time I do the REPL crashes on loading. They just switched the REPL to Babel 7 very recently, it still was version 6 by default just days ago, I guess they still have bugs.
PS: Strange, now I get Babel 6.26 again when I call the REPL URL (with no params, the plain empty URL), maybe they have some A/B testing going on, or have multiple servers and some still serve version 6?
Anyway, the transpiled code differs (much more code is created by Babel 7), but I get the same error in both versions:
mha@mint-virtual-machine ~ $ ~/lowjs-linux-x86_64-20190102/bin/low Babel6-code.js
TypeError: undefined not callable (property [Symbol wellknown '?Symbol.iterator?'] of [object Object])
at [anon] (deps/duktape/src-low/duktape.c:64945) internal
at [anon] (/home/mha/Babel6-code.js:12) strict preventsyield
mha@mint-virtual-machine ~ $ ~/lowjs-linux-x86_64-20190102/bin/low Babel7-code.js
TypeError: undefined not callable (property [Symbol wellknown '?Symbol.iterator?'] of [object Object])
at [anon] (deps/duktape/src-low/duktape.c:64945) internal
at [anon] (/home/mha/Babel7-code.js:51) strict preventsyield```
No more error, the initial test using the Linux binary works! Has the device image been updated to include this patch yet?
EDIT:
Okay, I see that this is not yet the case.
@neoniousTR So..... I just updated, and the device seems to be in an endless loop of starting and crashing. The yellow LED is turned on for a few seconds and then dies, some blinking, then the cycle continues. I unplugged it and after powering on the cycle continues. Not reachable over the network.
May be network related.
After factory reset performed according to https://www.lowjs.org/documentation/neonious-one.html WiFi works, but only port 8443, no reaction on port 8000. As soon as I plug in the Ethernet I get the on/off cycle again, with a running ping showing "timeout" and responses in intervals.
Well, should not happen. Most probably related to the new JIT compiler which takes too much mem.
Will try out tonight, should be easy to fix. But good that the device is not bricked.
Sorry that you cannot continue directly.
Is there an update yet?
Although even if there is, right now I don't know how to get it. The only thing that worked was the factory-reset image with WiFi as a server. I just tried switching it to using an existing access point and I cannot reach the system even with a ping. It also periodically disappears from the list of systems on my Fritz Box. I just can't reach it. I could do another reset and access it again when it acts as its own AP, but then I don't have an Internet connection.
Can I flash the device over the USB connection?
@neoniousTR I just want to make sure my email from yesterday did not land in your spam folder...
Hallo Thomas,
Im Changelog steht seit dem Update, nachdem ich nicht mehr aufs Gerät zugreifen konnte, nichts neues drin. Ich frage daher lieber noch einmal nach, bevor ich den Update des gerade erhaltenen neuen boards starte...
Beste Grüße
-- just a note that this bug is fixed and closed, as I am seeing many people coming here from Google --
This is still an issue I am having when trying to pull the data returned from a promise in react native.