twenties: Move setup script from boot file to run at install time ins… - #4271
Conversation
…tead. Thanks @cookesan for the help in https://github.com/orgs/espruino/discussions/7982.
| { "name": "twenties.boot.js", "url": "boot.js" }, | ||
| { "name": "twenties", "url": "lib.js" } | ||
| { "name": "twenties", "url": "lib.js" }, | ||
| { "name": "RAM", "content": "require('twenties').setup();" } |
There was a problem hiding this comment.
I tried doing
{ "name": "RAM", "url": "setup.js" }where setup.js would be
require('twenties').setup()but then it couldn't access the twenties library that was just uploaded with this error
>��Uncaught ReferenceError: "twenties" is not defined
at REPL (:1:9)
require(twenties).setup();;Bluetooth.println("OK")
^
>Uncaught ReferenceError: "twenties" is not defined
at REPL (:1:9)
require(twenties).setup();;Bluetooth.println("OK")
^
>@gfwilliams is that expected?
There was a problem hiding this comment.
OK - I should have tested a bit more. Doing
{ "name": "RAM", "url": "setup.js", "evaluate":true }works.
There was a problem hiding this comment.
It looks like there might have been some quoting error in that code? Eg require(twenties).setup() should have been require('twenties').setup() - so I wonder where along the line that got lost?
There was a problem hiding this comment.
As I said, when adding "evaluate":true it works so I guess I should do that?
But just to go back and verify the result I still get the following error (if I go without "evalutate":true):
Execution Interrupted
____ _
| __|___ ___ ___ _ _|_|___ ___
| __|_ -| . | _| | | | | . |
|____|___| _|_| |___|_|_|_|___|
|_| espruino.com
2v29.118 (c) 2026 G.Williams
>��Uncaught ReferenceError: "twenties" is not defined
at REPL (:1:9)
require(twenties).setup();;Bluetooth.println("OK")
^
>Uncaught ReferenceError: "twenties" is not defined
at REPL (:1:9)
require(twenties).setup();;Bluetooth.println("OK")
^
>
If setup.js is either/or:
require('twenties').setup();require("twenties").setup();
Not sure if this is a bug - but your previous reaction seems to indicate it might be.
There was a problem hiding this comment.
It's tricky, evaluate:true isn't really meant to be used like that - it's basically saying 'this code should be evaluated and the response put in a file'. I'd be pretty sure that is a bug, yes.
But I just tried here and it works fine for me! I changed the _example_app to add: { "name": "RAM", "content": "require('Storage').list();" } to the end.
I followed it through with a debugger and I can't see anywhere the code would be changed, and indeed I see:
<COMMS> Response: "OK\r"
<COMMS> Upload RAM => "require('Storage').list();" (26b)
<COMMS> Response: "OK\r"
In the Chrome debug console so it's doing everything right. Can you check the debug console in yours?
Is your fork up to date with the main repo? Maybe the core in your version is out of date or something. Maybe you could host it on your repo at https://thyttan.github.io/BangleApps so that I can debug it here?
There was a problem hiding this comment.
But I just tried here and it works fine for me! I changed the
_example_appto add:{ "name": "RAM", "content": "require('Storage').list();" }to the end. And that still gives me the error.
Yes, so using "content": someJS works on my end as well. It's when I put the someJS in a file "setup.js" an put { "name": "RAM", "url": "setup.js"} in the metadata.
I put it on my app-loader branch:
- https://github.com/thyttan/BangleApps/blob/app-loader/apps/twenties/metadata.json#L16-L16
- https://github.com/thyttan/BangleApps/blob/app-loader/apps/twenties/setup.js
It's on https://thyttan.github.io/BangleApps/?q=twenties now.
This is my output when running from thyttan.github.io:
Comms.debug()
undefined
index.js:54 =========== Queued Operation App Upload
index.js:57 =========== Starting Operation App Upload
espruinotools.js:145 Minifying
espruinotools.js:145 Minification complete
espruinotools.js:145 Minifying
espruinotools.js:145 Minification complete
comms.js:250 <COMMS> uploadApp: twenties, RAM, twenties.info
comms.js:139 <COMMS> reset
uart.js:1361 <UART> Sending "\u0003\u0010reset();\n"
uart.js:1361 <UART> Sent
comms.js:142 <COMMS> reset: got ""
comms.js:145 <COMMS> reset: no response. waiting 7...
uart.js:1361 <UART> Sending "\u0003"
uart.js:1361 <UART> Sent
comms.js:142 <COMMS> reset: got ""
comms.js:145 <COMMS> reset: no response. waiting 6...
uart.js:1361 <UART> Sending "\u0003"
uart.js:1361 <UART> Sent
comms.js:142 <COMMS> reset: got ""
comms.js:145 <COMMS> reset: no response. waiting 5...
uart.js:1361 <UART> Sending "\u0003"
uart.js:1361 <UART> Sent
comms.js:142 <COMMS> reset: got ""
comms.js:145 <COMMS> reset: no response. waiting 4...
uart.js:1361 <UART> Sending "\u0003"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "\r\u001b[JExecution Interrupted\r\n"
uart.js:1361 <UART> Received "\u001b[?7l\r\n ____ _ \r\n| __|___ ___ ___ _ _|_|___ ___ \r\n| __|_ -| . | _| | | | | . |\r\n|____|___| _|_| |___|_|_|_"
uart.js:1361 <UART> Received "|___|\r\n |_| espruino.com\r\n 2v29.118 (c) 2026 G.Williams\r\n\r\n>"
comms.js:142 <COMMS> reset: got "\r\u001b[JExecution Interrupted\r\n\u001b[?7l\r\n ____ _ \r\n| __|___ ___ ___ _ _|_|___ ___ \r\n| __|_ -| . | _| | | | | . |\r\n|____|___| _|_| |___|_|_|_|___|\r\n |_| espruino.com\r\n 2v29.118 (c) 2026 G.Williams\r\n\r\n>"
comms.js:151 <COMMS> reset: rebooted - sending commands to clear out any boot code
uart.js:1361 <UART> Sending "\u0010clearInterval();clearWatch();global.Bangle&&Bangle.removeAllListeners();E.removeAllListeners();global.NRF&&NRF.removeAllListene"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "rs();\n"
uart.js:1361 <UART> Sent
comms.js:154 <COMMS> reset: complete.
comms.js:125 <COMMS> showMessage "Installing\ntwenties..."
uart.js:1361 <UART> Sending "\u0010E.showMessage(\"Installing\\ntwenties...\",{\"title\":\"App Loader\",\"uploadProgress\":1066})\n"
uart.js:1361 <UART> Sent
comms.js:277 <COMMS> Upload twenties => "{®getTimeAtNextBuzz=()¢{workStart=¸Date();workEn..." (906b, binary)
uart.js:1361 <UART> Sending "\u0010\u0001`\u0019{\"fn\":\"twenties\",\"s\":906}"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "\u0006"
uart.js:1361 <UART> Got ACK
uart.js:1361 <UART> Sending "\u0010\u0001��{®getTimeAtNextBuzz=()¢{workStart=¸Date();workEnd=¸Date();workStart.setHours(Ô\b,Ó,Ó,Ó);workEnd.setHours(Ô\u0012,Ó,Ô\u0014,Ó);®isWork"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "Time=(d)¢d.getDay()%Ô\u0006�d�workStart�d<workEnd;®isLookAwayTime=(d)¢d.getMinutes()%Ô\u0014�Ó�d.getSeconds()<Ô\u0014;®NOW=¸Date();t=workStart"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending ".getHours()*3600000+workStart.getMinutes()*60000;£(isWorkTime(NOW)){£(isLookAwayTime(NOW)){t=NOW.getHours()*3600000+NOW.getMinut"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "es()*60000+Ô\u0014*Õè\u0003;}¤{t=NOW.getHours()*3600000+(NOW.getMinutes()+(Ô\u0014-NOW.getMinutes()%Ô\u0014))*60000;}}«t;};exports.buzzAndSetup=ª(){"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "Bangle.buzz();exports.setup();};®JS_DELETE_ALARM_THEN_BUZZ_AND_SETUP=ÑUrequire(\"sched\").setAlarm(\"twenties\", undefined); require"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "('twenties').buzzAndSetup();;®S=require(Ñ\u0005sched);exports.setup=ª(){®TIME_AT_NEXT_BUZZ=getTimeAtNextBuzz();alarm={on:´,t:TIME_AT"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "_NEXT_BUZZ,dow:Ô>,hidden:´,msg:Ñ\bTwenties,group:Ñ\bTwenties,js:JS_DELETE_ALARM_THEN_BUZZ_AND_SETUP};S.setAlarm(Ñ\btwenties,alarm);"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "S.reload();};}"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "\u0006"
uart.js:1361 <UART> Got ACK
comms.js:277 <COMMS> Upload RAM => "require(Ñ\btwenties).setup();" (28b)
uart.js:1361 <UART> Sending "\u0010require(Ñ\btwenties).setup();;Bluetooth.println(\"OK\")\n"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "Uncaught ReferenceError: \"twenties\" is not defined\r\n at REPL (:1:9)\r\nrequire(twenties).setup();;Bluetooth.println(\"OK\")\r\n "
comms.js:184 <COMMS> Response: "require(twenties).setup();;Bluetooth.println(\"OK\")\r"
comms.js:293 First attempt failed: Unexpected response "require(twenties).setup();;Bluetooth.println(\"OK\")"
(anonymous) @ comms.js:293
Promise.then
doUploadFiles @ comms.js:292
Promise.then
doUploadFiles @ comms.js:292
(anonymous) @ comms.js:315
Promise.then
doUpload @ comms.js:314
Promise.then
(anonymous) @ comms.js:326
(anonymous) @ comms.js:249
Promise.then
uploadApp @ comms.js:248
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1054
(anonymous) @ index.js:58
Promise.then
(anonymous) @ index.js:56
startOperation @ index.js:55
uploadApp @ index.js:1054
(anonymous) @ index.js:975
comms.js:297 Using lower upload chunk size (2048 ==> 256)
(anonymous) @ comms.js:297
Promise.then
doUploadFiles @ comms.js:292
Promise.then
doUploadFiles @ comms.js:292
(anonymous) @ comms.js:315
Promise.then
doUpload @ comms.js:314
Promise.then
(anonymous) @ comms.js:326
(anonymous) @ comms.js:249
Promise.then
uploadApp @ comms.js:248
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1054
(anonymous) @ index.js:58
Promise.then
(anonymous) @ index.js:56
startOperation @ index.js:55
uploadApp @ index.js:1054
(anonymous) @ index.js:975
comms.js:277 <COMMS> Upload RAM => "require(Ñ\btwenties).setup();" (28b)
uart.js:1361 <UART> Sending "\u0010require(Ñ\btwenties).setup();;Bluetooth.println(\"OK\")\n"
uart.js:1361 <UART> Received " ^\r\n>"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "Uncaught ReferenceError: \"twenties\" is not defined\r\n at REPL (:1:9)\r\nrequire(twenties).setup();;Bluetooth.println(\"OK\")\r\n "
comms.js:184 <COMMS> Response: "require(twenties).setup();;Bluetooth.println(\"OK\")\r"
comms.js:301 Second attempt failed - bailing. Unexpected response "require(twenties).setup();;Bluetooth.println(\"OK\")"
(anonymous) @ comms.js:301
Promise.then
(anonymous) @ comms.js:300
Promise.then
doUploadFiles @ comms.js:292
Promise.then
doUploadFiles @ comms.js:292
(anonymous) @ comms.js:315
Promise.then
doUpload @ comms.js:314
Promise.then
(anonymous) @ comms.js:326
(anonymous) @ comms.js:249
Promise.then
uploadApp @ comms.js:248
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1054
(anonymous) @ index.js:58
Promise.then
(anonymous) @ index.js:56
startOperation @ index.js:55
uploadApp @ index.js:1054
(anonymous) @ index.js:975
ui.js:79 <TOAST>[error] Upload of Twenties failed, Unexpected response "require(twenties).setup();;Bluetooth.println(\"OK\")"
index.js:63 =========== Operation App Upload Complete
uart.js:1361 <UART> Received " ^\r\n>"This is my output when running from localhost:
Comms.debug()
undefined
index.js:54 =========== Queued Operation App Upload
index.js:57 =========== Starting Operation App Upload
espruinotools.js:145 Minifying
espruinotools.js:145 Minification complete
espruinotools.js:145 Minifying
espruinotools.js:145 Minification complete
comms.js:250 <COMMS> uploadApp: twenties, RAM, twenties.info
comms.js:139 <COMMS> reset
uart.js:1361 <UART> Sending "\u0003\u0010reset();\n"
uart.js:1361 <UART> Sent
comms.js:142 <COMMS> reset: got ""
comms.js:145 <COMMS> reset: no response. waiting 7...
uart.js:1361 <UART> Sending "\u0003"
uart.js:1361 <UART> Sent
comms.js:142 <COMMS> reset: got ""
comms.js:145 <COMMS> reset: no response. waiting 6...
uart.js:1361 <UART> Sending "\u0003"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "\r\u001b[JExecution Interrupted\r\n\u001b[?7l\r\n ____ _ \r\n| __|___ ___ ___ _ _|_|___ ___ \r\n| __|_ -| . | _| | | | | . |\r\n"
uart.js:1361 <UART> Received "|____|___| _|_| |___|_|_|_|___|\r\n |_| espruino.com\r\n 2v29.118 (c) 2026 G.Williams\r\n\r\n>"
comms.js:142 <COMMS> reset: got "\r\u001b[JExecution Interrupted\r\n\u001b[?7l\r\n ____ _ \r\n| __|___ ___ ___ _ _|_|___ ___ \r\n| __|_ -| . | _| | | | | . |\r\n|____|___| _|_| |___|_|_|_|___|\r\n |_| espruino.com\r\n 2v29.118 (c) 2026 G.Williams\r\n\r\n>"
comms.js:151 <COMMS> reset: rebooted - sending commands to clear out any boot code
uart.js:1361 <UART> Sending "\u0010clearInterval();clearWatch();global.Bangle&&Bangle.removeAllListeners();E.removeAllListeners();global.NRF&&NRF.removeAllListene"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "rs();\n"
uart.js:1361 <UART> Sent
comms.js:154 <COMMS> reset: complete.
comms.js:125 <COMMS> showMessage "Installing\ntwenties..."
uart.js:1361 <UART> Sending "\u0010E.showMessage(\"Installing\\ntwenties...\",{\"title\":\"App Loader\",\"uploadProgress\":1066})\n"
uart.js:1361 <UART> Sent
comms.js:277 <COMMS> Upload twenties => "{®getTimeAtNextBuzz=()¢{workStart=¸Date();workEn..." (906b, binary)
uart.js:1361 <UART> Sending "\u0010\u0001`\u0019{\"fn\":\"twenties\",\"s\":906}"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "\u0006"
uart.js:1361 <UART> Got ACK
uart.js:1361 <UART> Sending "\u0010\u0001��{®getTimeAtNextBuzz=()¢{workStart=¸Date();workEnd=¸Date();workStart.setHours(Ô\b,Ó,Ó,Ó);workEnd.setHours(Ô\u0012,Ó,Ô\u0014,Ó);®isWork"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "Time=(d)¢d.getDay()%Ô\u0006�d�workStart�d<workEnd;®isLookAwayTime=(d)¢d.getMinutes()%Ô\u0014�Ó�d.getSeconds()<Ô\u0014;®NOW=¸Date();t=workStart"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending ".getHours()*3600000+workStart.getMinutes()*60000;£(isWorkTime(NOW)){£(isLookAwayTime(NOW)){t=NOW.getHours()*3600000+NOW.getMinut"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "es()*60000+Ô\u0014*Õè\u0003;}¤{t=NOW.getHours()*3600000+(NOW.getMinutes()+(Ô\u0014-NOW.getMinutes()%Ô\u0014))*60000;}}«t;};exports.buzzAndSetup=ª(){"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "Bangle.buzz();exports.setup();};®JS_DELETE_ALARM_THEN_BUZZ_AND_SETUP=ÑUrequire(\"sched\").setAlarm(\"twenties\", undefined); require"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "('twenties').buzzAndSetup();;®S=require(Ñ\u0005sched);exports.setup=ª(){®TIME_AT_NEXT_BUZZ=getTimeAtNextBuzz();alarm={on:´,t:TIME_AT"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "_NEXT_BUZZ,dow:Ô>,hidden:´,msg:Ñ\bTwenties,group:Ñ\bTwenties,js:JS_DELETE_ALARM_THEN_BUZZ_AND_SETUP};S.setAlarm(Ñ\btwenties,alarm);"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Sending "S.reload();};}"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "\u0006"
uart.js:1361 <UART> Got ACK
comms.js:277 <COMMS> Upload RAM => "require(Ñ\btwenties).setup();" (28b)
uart.js:1361 <UART> Sending "\u0010require(Ñ\btwenties).setup();;Bluetooth.println(\"OK\")\n"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "Uncaught ReferenceError: \"twenties\" is not defined\r\n at REPL (:1:9)\r\nrequire(twenties).setup();;Bluetooth.println(\"OK\")\r\n "
comms.js:184 <COMMS> Response: "require(twenties).setup();;Bluetooth.println(\"OK\")\r"
comms.js:293 First attempt failed: Unexpected response "require(twenties).setup();;Bluetooth.println(\"OK\")"
(anonymous) @ comms.js:293
Promise.then
doUploadFiles @ comms.js:292
Promise.then
doUploadFiles @ comms.js:292
(anonymous) @ comms.js:315
Promise.then
doUpload @ comms.js:314
Promise.then
(anonymous) @ comms.js:326
(anonymous) @ comms.js:249
Promise.then
uploadApp @ comms.js:248
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1054
(anonymous) @ index.js:58
Promise.then
(anonymous) @ index.js:56
startOperation @ index.js:55
uploadApp @ index.js:1054
(anonymous) @ index.js:975
comms.js:297 Using lower upload chunk size (2048 ==> 256)
(anonymous) @ comms.js:297
Promise.then
doUploadFiles @ comms.js:292
Promise.then
doUploadFiles @ comms.js:292
(anonymous) @ comms.js:315
Promise.then
doUpload @ comms.js:314
Promise.then
(anonymous) @ comms.js:326
(anonymous) @ comms.js:249
Promise.then
uploadApp @ comms.js:248
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1054
(anonymous) @ index.js:58
Promise.then
(anonymous) @ index.js:56
startOperation @ index.js:55
uploadApp @ index.js:1054
(anonymous) @ index.js:975
comms.js:277 <COMMS> Upload RAM => "require(Ñ\btwenties).setup();" (28b)
uart.js:1361 <UART> Sending "\u0010require(Ñ\btwenties).setup();;Bluetooth.println(\"OK\")\n"
uart.js:1361 <UART> Received " ^\r\n>"
uart.js:1361 <UART> Sent
uart.js:1361 <UART> Received "Uncaught ReferenceError: \"twenties\" is not defined\r\n at REPL (:1:9)\r\nrequire(twenties).setup();;Bluetooth.println(\"OK\")\r\n "
comms.js:184 <COMMS> Response: "require(twenties).setup();;Bluetooth.println(\"OK\")\r"
comms.js:301 Second attempt failed - bailing. Unexpected response "require(twenties).setup();;Bluetooth.println(\"OK\")"
(anonymous) @ comms.js:301
Promise.then
(anonymous) @ comms.js:300
Promise.then
doUploadFiles @ comms.js:292
Promise.then
doUploadFiles @ comms.js:292
(anonymous) @ comms.js:315
Promise.then
doUpload @ comms.js:314
Promise.then
(anonymous) @ comms.js:326
(anonymous) @ comms.js:249
Promise.then
uploadApp @ comms.js:248
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1065
Promise.then
(anonymous) @ index.js:1054
(anonymous) @ index.js:58
Promise.then
(anonymous) @ index.js:56
startOperation @ index.js:55
uploadApp @ index.js:1054
(anonymous) @ index.js:975
ui.js:79 <TOAST>[error] Upload of Twenties failed, Unexpected response "require(twenties).setup();;Bluetooth.println(\"OK\")"
index.js:63 =========== Operation App Upload Complete
uart.js:1361 <UART> Received " ^\r\n>"There was a problem hiding this comment.
also: What settings do you have currently enabled in your app loader? Maybe it's some combination that i don't have on here...
The only toggled on settings:
- Pretokenise apps
- Send app analytics
There was a problem hiding this comment.
Ok, thanks. I see it now - yes, it's when uploading pretokenised JS direct to the REPL, which doesn't work. I'll get a fix in for that now.
... but the question I guess is why did you change away from { "name": "RAM", "content": "require('twenties').setup();" } ?
There was a problem hiding this comment.
Thank you Gordon!
... but the question I guess is why did you change away from
{ "name": "RAM", "content": "require('twenties').setup();" }?
For twenties I see that is unnecessary, true. The thing is I want to use it for some more involved setup for quicklaunch. And it will not be desirable (or even possible?) to have long sections of js in the metadata. So I wanted to test this pattern.
It was: Error: App twenties's RAM has evaluate:true but is not valid JS expression
…tead.