B4J Library [Web][BANano] Website/App/PWA library with Abstract Designer support

BANano7.jpg


BANano7architecture2.jpg



INTRO

BANano is a new B4J library to websites/webapps with (offline) Progressive Web App support. Unlike its big brother ABMaterial, BANano does not rely on any particular framework like Materialize CSS. You will have to write that part yourself, but on the other hand, you have the choice to pick which one.

Why a second framework? Well, from the start ABMaterial was build with a back server in mind. B4J has great support to setup a very powerful jServer to handle web requests. Which does mean all intelligence is at the server side and you have the full power of B4J to do whatever you want (secure database access, serial communication, cache control etc). With B4JS, some of this intelligence could be transferred to the browser side, but the app still needs internet/intranet access so this is as far as it could go.

BANano is a different animal. It can use a Service Worker to 'install' the web app in the browser, so it can also work when the user is offline. While ABMaterial builds the page from the server side, BANano builds it from the browser side. This means EVERYTHING you write in B4J is transpiled to Javascript, HTML and CSS.

But with great power comes great responsibility! Unlike ABMaterial, some basic knowledge of HTML, CSS and to some extend Javascript is needed to build BANano apps. It makes excellent use of B4X's SmartStrings to create the HTML part of the app. BANano gives you a set of tools to write your own wrapper around any framework (MiniCSS, Skeleton, Spectre, Bootstrap, ...), which then can be easily used to quickly build webapps/websites.

OVERVIEW

A quick overview to show the different uses of both frameworks:

overview.png

So both frameworks have their specific target, both for the programmer and the app you want to make.

BANano is written from scratch, so although it is similar to B4JS, both support different things. B4JS is build on jQuery, while BANano uses Umbrella JS (a lighter form of jQuery, about 50x smaller) and Mustache to build the HTML.

BANano does also support some different B4J than B4JS: e.g. things like CreateMap, better support for SmartStrings etc.

Abstract Designer support in v2.0+

BANano1.21.png


LICENSE

Freeware/Donationware License

B4J is Copyright (c) 2010 - 2018 by Anywhere Software All Rights Reserved.
LIBRARY (Library/library): B4J library files BANano.jar and BANano.xml (by Alain Bailleul)
SOFTWARE (Software/software): Computer Software
APPLICATION (Application/application): Any end product as the result of compiling with an Anywhere Software product
SOURCE CODE: human-readable program statements written by a programmer or developer in a high-level or assembly language that are not directly readable by a computer and that need to be compiled into object code before they can be executed by a computer

BY USING THIS LIBRARY, YOU AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE.

1. THIS LIBRARY IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ANY COPYRIGHT HOLDER/AUTHOR/DEVELOPER BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,SPECIAL,INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY INCLUDING BUT NOT LIMITED TO LOSS OF DATA, FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER PROGRAMS OR LIBRARY, EVEN IF COPYRIGHT HOLDER/AUTHOR/DEVELOPER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

2. YOU MAY NOT COPY, SUB-LICENSE, REVERSE ENGINEER, DECOMPILE, DISASSEMBLE, OR MODIFY THIS LIBRARY IN ANY WAY.

3. YOU MAY NOT DISTRIBUTE THE LIBRARY ON ANY MEDIUM WITHOUT PRIOR NOTICE FROM ALAIN BAILLEUL ([email protected]). YOU HAVE TO ASK FOR PERMISSION IN ORDER TO MAKE THIS LIBRARY AVAILABLE FOR DISTRIBUTION OVER THE INTERNET OR ANY OTHER DISTRIBUTABLE MEDIUM.

4. YOU AGREE NOT TO DISTRIBUTE FOR A FEE AN APPLICATION USING THE LIBRARY THAT, AS ITS PRIMARY PURPOSE, IS DESIGNED TO BE AN AID IN THE DEVELOPMENT OF SOFTWARE FOR YOUR APPLICATION'S END USER. SUCH APPLICATION INCLUDES, BUT IS NOT LIMITED TO, A DEVELOPMENT IDE OR A B4J SOURCE CODE GENERATOR.

By possessing and/or using this library you are automatically agreeing to and show that you have read and understood the terms and conditions contained within this Freeware Software License Agreement. This Freeware Software License Agreement is then effective while you possess, use and continue to make use of these software products. If you do not agree with our Freeware Software License Agreement you must not possess or use our library products - this Freeware Software License Agreement will then not apply to you. This Freeware Software License Agreement is subject to change without notice.

Violators of this agreement will be prosecuted to the full extent of the law.

This library is free, however if you do enjoy it, please consider a donation to Alain Bailleul ([email protected]) for his time and efforts to make this library possible.

This license file (LICENSE.TXT) shall be included in all copies of the library or any distribution using the library in any form resulting from mechanical transformation or translation of the source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

If you have any questions regarding this license, please contact [email protected]

Cheers,

Alain
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Hi

Can you please add functionality to Log a nicer error when non existing files are added via BANano.AddJavascripfile that are not based on web resources.

For example, I have added a javascript file that does not exist, on purpose (i'm trying to merge files after build with post processor) and as expected

B4X:
java.io.FileNotFoundException: uoemock.js
etc etc

is generated when the files are being copied from resources to the various resource folders, because it does not exist. This happens during executing of the logs below...

B4X:
Copying file from Files to WebApp assets: bootstrap-switch.js
is run.

Adding a non-existing file with BANano.AddCSSFile does not generate an error even if the file does not exists ('im also merging my css files into one file).

Ta!
 

Mashiane

Expert
Licensed User
Longtime User
Hi, if its not going to be a hustle, can you please add a feature for the CallInlinePhp so that one can also specify a callback function? Please.

For example, I'm working on a rather large app and this is just the beginning of my inline php script...

B4X:
#if PHP
function CreateDB($servername,$username,$password,$db) {
    header('content-type: application/json; charset=utf-8');
    $conn = new mysqli($servername, $username, $password);
    if ($conn->connect_error) {
        $response = $conn->connect_error;
        $output = json_encode(array("response" => $response));
        die($soutput);
    }
    $sql = "CREATE DATABASE $db";
    if ($conn->query($sql) === TRUE) {
        $response = "OK";
    } else {
        $response = $conn->error;
    }
    $output = json_encode(array("response" => $response));
    echo($output);
    $conn->close();
}

function TestConnection($servername,$username,$password) {
    header('content-type: application/json; charset=utf-8');
    $conn = new mysqli($servername, $username, $password);
    if ($conn->connect_error) {
        $response = $conn->connect_error;
        $output = json_encode(array("response" => $response));
        die($soutput);
    } else {
        $response = "OK";
        $output = json_encode(array("response" => $response));
        echo($output);
    }
    $conn->close();
}

#End If

I fear that my result code will be rather massive and kinda hard to maintain...

B4X:
Sub BANano_CallInlinePHPResult(Success As Boolean, UniqueID As String, Result As String)
    If Success Then
        Select Case UniqueID
            Case "testconnection"
                Dim resp As Map = App.Json2Map(Result)
                Dim strresp As String = resp.Get("response")
                Select Case strresp
                    Case "OK"
                        App.ToastSuccess("Connection to MySQL successful!")
                    Case Else
                        Log(strresp)
                        App.ToastError(strresp)
                End Select
            Case "createdb"
                Dim resp As Map = App.Json2Map(Result)
                Dim strresp As String = resp.Get("response")
                Select Case strresp
                Case "OK"
                    App.ToastSuccess("MySQL Database created successful!")
                Case Else
                    Log(strresp)
                    App.ToastError(strresp)
                End Select
        End Select
    End If
End Sub

With a callback that receives a similar signature for CallInlinePHPResult, I can have these case statements separate and manageable.

Thanks in advance.
 

Mashiane

Expert
Licensed User
Longtime User
Hi

I have just picked up something with my code, can you please take a look when CreateMap is used with variable keys?

Reproduction
B4X:
Dim fld As Map = CreateMap(stableprimarykey:App.EnumFieldTypes.DB_INT)
Log(fld)

Result
B4X:
{_stableprimarykey: "INT"}

This works
B4X:
Dim fld As Map
fld.Initialize
fld.put(stableprimarykey,App.EnumFieldTypes.DB_INT)
log(fld)

Result - this is correct
B4X:
{id: "INT"}

Ta!
 

OliverA

Expert
Licensed User
Longtime User

alwaysbusy

Expert
Licensed User
Longtime User
Again ,do not post questions/requests/bugs in this thread. This post is for announcements on BANano only so it can be a reference point for users to find what has been changed over versions. Start a new thread with [BANano] in the subject. I do not react, investigate or take any action on posts in here because they can easily grow to full conversations.
 

alwaysbusy

Expert
Licensed User
Longtime User
BANano v3.09

TAKE A BACKUP!

CHANGES:

1. NEW: BANano .b4xlib libraries

The big change is the introduction of being able to make and use BANano libraries in the .b4xlib format.
This has a couple of profound advantages over normal .jar libraries for BANano:

a. Because the libraries are compiled at the same time as the app, BANano can remove classes that are not used in the app. This works best for libraries that use Custom Views.

E.g. suppose you made a big library with a lot of components like DatePickers, Grids, etc. If you don't use a certain component, then that code is not included in your final app. This can reduce the size of the generated app considerably.

I think the way BANano generates a build (very modular) is now paying off big time.
But, this really depends on how modular the library builder has written his library.

e.g. if a class is used in a method in a module, but this method is never called in your app, all the classes (and the DependsOnAsset, see 6) will still be included.

b. As all the assets are included in the .b4xlib, you don't have to worry about adding them in your app anymore: they are copied and included automatically. This means less clutter in your Files tab and no more .AddCSSFile or .AddJavascriptFile that are just needed for a library. You just have to worry about the assets you use in your app.

c. No more need to make a library in two steps (BuildAsLibrary + Compile to Library)

As a Library Builder, there is nothing special you have to do, except using:
B4X:
BANano.BuildAsB4Xlib("1.01")

I've tried it on all the libs and projects I have and it looks like it works, but maybe there are still some problems in it. I had to make a lot of changes to the core of BANano to make this possible, so the chance exists.

In short: TAKE A BACKUP! :)

2. NEW: The generated .js files are in Build (release) modus a lot smaller (tests showed sometimes 50% smaller)

3. CHANGE: UseServiceWorker is now by default false. You will have to set it to True if you want to use a Service worker.

4. NEW: MinifyOnline now also minifies CSS files

5. NEW: MergeAllCSSFiles and MergeAllJavascript files: will create one CSS and one JS file by mergin them.

6. NEW: DependsOnAsset

When creating e.g. a Custom View, you can set if it Depends on certain CSS, Javascript or other asset files.
For CSS and Javascript, you must still use the AddCSSFile & AddJavascriptFile in AppStart.

7. Because the Transpiler gets more and more options, I created a new object BANano.TranspilerOptions that hosts those options.

The old ones are marked DEPRECIATED (they still work, but will eventually be removed). A warning is shown.

8. NEW options: ShowWarningsDeadCode & RemoveDeadCode

Only works in Build

Shows a warning in the log if the transpiler suspects some code is dead (never used).
This is handy, especially in the final stage of development to remove code (or comment out) that is never used.

Methods with a _ in their name are always considerd to be needed.

You can then use the RemoveDeadCode property to prevent GENERATING dead javascript code.

9. Added the Fetch API: see https://www.b4x.com/android/forum/threads/banano-the-fetch-api.106666/

Download: https://www.b4x.com/android/forum/t...-abstract-designer-support.99740/#post-627764

Alwaysbusy
 

alwaysbusy

Expert
Licensed User
Longtime User
BANano v4.07

TAKE A BACKUP! <----


CHANGES:

1. [NEW] Besides the build-in Base64, there is an extra library based on another framework you can use in case you have problems with e.g. Chinese characters.

B4X:
Dim b64 As Base64
b64.Initialize
Log(b64.ToBase64("dankogai"))  ' ZGFua29nYWk=
Log(b64.Tobase64("小飼弾"))    ' 5bCP6aO85by+
Log(b64.ToBase64URI("小飼弾"))  ' 5bCP6aO85by-

Log(b64.FromBase64("ZGFua29nYWk="))  ' dankogai
Log(b64.FromBase64("5bCP6aO85by+"))  ' 小飼弾
Log(b64.FromBase64URI("5bCP6aO85by-"))  ' 小飼弾

Dim pngBase64 As String = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
Dim b() As Byte = b64.FromBase64Bytes(pngBase64)
' because the Log() method of B4J does not support printing a byte array
BANano.Console.Log(b)

2. [NEW] Added polyfills for the Fetch and AbortController APIs. They will be injected if you set the parameter BANano.TranspilerOptions.ShowWarningsUnsupportedForOldBrowsers = true

3. [FIX] Chained methods sometimes wrongly transpiled

4. [NEW] you are now able to use additional parameters using an Array in the WaitFor method

B4X:
BANano.WaitFor(PromiseResult, Me, "secondAsyncWait", Array(20))
Log("secondAsyncWait result:" & PromiseResult)

5. [NEW] I have added a warning in the B4J log if the method does not exist in a WaitFor call

B4X:
[WARNING]: The method WaitFor in banano_ready can not find '"DoesNotExist"'!

6. [FIX] Bad transpiling with BANano.Iif()

B4X:
Dim x As Object = Null
Dim xIsNull as Boolean = BANano.Iif(x = null, true, false) ' -> results in false because of (_x = null) instead of ==

7. [NEW] Try Catch can now also use the Javascript Finally keyword. See the example for what the difference is.

B4X:
Dim num As Int = 10
Dim divider As Int = 0
Try
   If divider = 0 Then
      BANano.Throw("You can not divide by 0!")
   Else
      Log(num/divider)
   End If 
Catch
   Log(LastException)
   ' will still do the Finally part, but not the "After the Try" log.
   Return
BANano.Finally 'ignore
   Log("Always doing this")         
End Try

Log("After the Try")

8. [NEW] Finally keyword also on Promise and Fetch

9. [CHANGE] BANanoEvent.CurrentTarget and RelatedTarget are now of the type Object

10. [CHANGE] BANanoElement.Last, First, Closest do now not return an Array anymore but directly the Element

11. [FIX] promise didn't bubble if BANano.CallBack is not called inside a sub. The

e.g.
B4X:
Private Sub Sub1() 'ignore
   Dim result, response, error as object
   Dim promise As BANanoPromise
   promise.CallSub(Me, "Sub2", Null)
   promise.Then(response)
       result = response
   promise.Else(error)
       result = error
   promise.Finally
       Log(result)
   promise.End
End Sub

'didn't work as _BANp,_B aren't passed to Sub3 as additional arguments, so calling BANano.ReturnThen() didn't work in Sub3
Private Sub Sub2()
   Sub3
End Sub

Private Sub Sub3()
   BANano.ReturnThen(True)
End Sub

12. [NEW] The Fetch API does now also have ...Wait methods like a Promise already has

B4X:
Dim fetch As BANanoFetch
Dim response As BANanoFetchResponse
Dim json As Object
fetch.Initialize("https://jsonplaceholder.typicode.com/todos/1", Null)
fetch.Then(response) ' not a wait
   Log("1")
   Return response.Json 'ignore
fetch.ThenWait(json) 'a wait
   Log("2")
   BANano.Sleep(1000)
   Log(json)
fetch.ElseWait(response) ' a wait
   Log("3")
   BANano.Sleep(1000)
   Log(response)
fetch.FinallyWait ' a wait
   Log("4")
   BANano.Sleep(1000)
   Log("Finally")
fetch.end

13. [FIX] Trasnpiler problem with BANanoElement.Last

14. [FIX] I fixed some problems where a method without parameters and written with () e.g. Initialize() was badly transpiled.
There are problably more methods that don't accept parameters where the () can give a problem. I will need to fix them as we discover them. General rule is, no params, don't use ().

15. [NEW] Support for importing an ES6 module.

IMPORTANT: Adding an ES6 module must use the BANano.Header.AddJavascriptES6File("math.js") method instead of the normal BANano.Header.AddJavascriptFile()!
This is because in Javascript a module is loaded differenly than a normal javascript file.

Content of math.js
B4X:
let sumAll = (a, b) => {return a + b;}
let subtractAll = (a, b) => {return a - b;}
let divideAll = (a, b) => {return a / b;}
let multiplyAll = (a, b) => {return a * b;}
let findModulus = (a, b) => {return a % b;}

export {sumAll, subtractAll, divideAll, multiplyAll, findModulus};

Example usage in B4J:
B4X:
Dim math As BANanoObject
Dim mathProm As BANanoPromise
mathProm = BANano.Import("math.js") ' <--- is an ES6 module
mathProm.Then(math)
   Log(math.RunMethod("sumAll", Array(5,6)))
mathProm.End

I also added a BANano.ImportWait() method, which directly returns the ES6 module as a BANanoObject.

16. [NEW] Support for nested b4xlib libraries.

IMPORTANT: There is currently a bug in B4J that prevents you to use them in Release mode. Erel has already fixed this bug and it will be possible in the next release of B4J.

17. [FIX] HandleEvents and On now converts the method parameter to lowercase

18. [NEW] The throw statement allows you to create a custom error.

Technically you can throw an exception (throw an error).

e.g.
B4X:
BANano.Throw("This number is not valid")
BANano.Throw(500)

19. [NEW] New methods on the BANano object that cover the 'Is' in B4J:

B4X:
BANano.IsBoolean(var)
BANano.IsDate(var)
BANano.IsDomelement(var)
BANano.IsFunction(var)
BANano.IsNull(var)
BANano.IsNumber(var)
BANano.IsObject(var)
BANano.IsMap(var)
BANano.IsList(var)
BANano.IsJson(var)
BANano.IsString(var)
BANano.IsUndefined(var)
BANano.IsError(var)
BANano.IsEmpty(var)
BANano.Existy(var)
BANano.IsCapitalzed(var)
BANano.IsDecimal(var)
BANano.IsInteger(var)

20. [FIX] LastMessageExeception does now not automatically append .Message (sometimes errors did not have a message and hence were not printed)

21. [NEW] BANanoObject.GetFunction and BANanoObject.Execute. Gets a function and then you can directly call the Execute method on it.

22. [REMOVED] DetectNoES6, ShowWarningsUnsupportedForOldBrowsers and the event are removed. They are replaced with a new system, see 24

23. [FIX] The callback in BANano.Window.SetTimeOut and BANano.Window.SetInterval was wrongly transpiled.

24. [NEW] new BANano controlword: BANano_OLDBROWSER

Must be used like this (the if can NOT contain extra conditions!):
B4X:
if BANano.OLDBROWSER then
   ' your old browser compatible stuff
else
   ' your ES6 stuff
end if

Example (here old browsers do not support wait methods or sleep):
B4X:
Dim promise As BANanoPromise
' the results from the promise
Dim Result As Map
Dim Error As String
               
' call the UploadAll method 
promise.CallSub(Me, "UploadAllFiles", Array(UploadedFiles))
 
If BANano.OLDBROWSER Then
      ' when it is done, we can use whatever the UploadAll has returned in its BANano.ReturnThen call
      ' we use can't use ThenWait here
      promise.Then(Result)
          ' let's show all our urls
          For i = 0 To Result.Size - 1
              Log(Result.GetKeyAt(i) & "=" & Result.GetValueAt(i))
          Next
      promise.Then(Null)
          ' now how about next we make a HTTP request after we got all files
          DoHTTP("assets/product.json")
          promise.Else(Error)
          Log("Error: " & Error)
      promise.End
Else
      ' when it is done, we can use whatever the UploadAll has returned in its BANano.ReturnThen call
      ' we use the ThenWait here because we use ...Wait functions or in this case a Sleep
      promise.ThenWait(Result)
          Log("Done, going to sleep for 2 seconds just to demonstrate ThenWait()...")
          Sleep(2000)
          Log("Printing result after 2 seconds")
          ' let's show all our urls
          For i = 0 To Result.Size - 1
              Log(Result.GetKeyAt(i) & "=" & Result.GetValueAt(i))
          Next
      promise.Then(Null)
          ' now how about next we make a HTTP request after we got all files
          DoHTTP("assets/product.json")
          promise.Else(Error)
          Log("Error: " & Error)
      promise.End
End If

a. two js files are created: one normal app.js for new browsers, one ES5_app.js for old browsers
b. In the html file, the scripts are no longer loaded with the <script> tags, but with a loadjs script. A check is done if the browser does support ES6 stuff. If it does the normal app.js is loaded, else the ES5_app.js.
c. all your own Wait methods will NOT be generated in the ES5_app.js

25. [NEW] a new polyfill was used for the Promise in old browsers which appears to be better than the old one.

26. [NEW] nested Promises are now allowed

27. [FIX] Transpiler error in GetAllResponseHeaders

28. [FIX] Consts on XMLHttpRequest: DONE, HEADERS_RECEIVED, LOADING, OPENED, UNSENT were not transpiled

30. [FIX] Transpiler error in BANanoXMLHttpRequest.SetWithCredentials()

31. [FIX] BANano.Window.RequestAnimationFrame now uses a callback syntax for its parameters. Also BANano.Window.CancelAnimationFrame was added.

32. [FIX] Datetime.DateFormat and BANano.Timeformat fix used in a condition or log()

33. [NEW] Conditional loading of assets.

Use the BANano.Header.AddCSSFileForLater, BANano.Header.AddJavascriptFileForLater and BANano.Header.AddJavascriptES6FileForLater to 'declare' which assets will be used.
Other assets like pictures, json or fonts this is not needed as they will be copied automatically if they are in the /Files folder.

* Check if bundle has already been defined
B4X:
BANano.AssetsIsDefined(bundleName as String) As Boolean

* Loads a bundle of assets and returns a promise.
If the asset is a CSS or JS file, it must have been Added with the BANano.header.Add...ForLater() methods
B4X:
' in Sub AppStart()
BANano.Header.AddCSSFileForLater("mini-nord.min.css")
...
' in Sub BANano_Ready()
Dim pathsNotFound() as String
If BANano.AssetIsDefined("Loader") = False then
   Dim prom as BANanoPromise = BANano.AssetsLoad("Loader", Array("./assets/1.jpg", "./styles/mini-nord.min.css"))
   prom.Then(Null)
       Log("Loader has been loaded!")
   prom.Else(pathsNotFound)
       Log("Doh! Loader has not been loaded completely!")
       For Each path As String In pathsNotFound
           Log(path)
       Next
   prom.End
End if

* Loads a bundle of assets and uses the BANano bundleEventName_AssetsLoaded() event
If the asset is a CSS or JS file, it must have been Added with the BANano.header.Add...ForLater() methods
The bundle name and eventName is the same.
B4X:
 ' in Sub AppStart()
 BANano.Header.AddCSSFileForLater("mini-nord.min.css")
 ...
 ' in Sub BANano_Ready()
 BANano.AssetsLoadEvent(Me, "Loader", Array("./assets/1.jpg", "./styles/mini-nord.min.css"))
 ...
 Sub loader_AssetsLoaded(pathsNotFound() As String)
   If BANano.IsNull(pathsNotFound) = False Then
       Log("Doh! Loader has not been loaded completely!")
       For Each path As String In pathsNotFound
           Log(path)
       Next
   Else
       Log("Loader has been loaded!") 
   End If
 End Sub

* Loads a bundle of assets and waits until it is loaded. Returns a String array containing the paths that failed.
If the asset is a CSS or JS file, it must have been Added with the BANano.header.Add...ForLater() methods
B4X:
 ' in Sub AppStart()
 BANano.Header.AddCSSFileForLater("mini-nord.min.css")
 ...
 ' in Sub BANano_Ready()
 Dim pathsNotFound() as String
 If BANano.AssetIsDefined("Loader") = False then
   pathsNotFound = BANano.AssetsLoadWait("Loader", Array("./assets/1.jpg", "./styles/mini-nord.min.css"))
   If BANano.IsNull(pathsNotFound) = False Then
       Log("Doh! Loader has not been loaded completely!")
       For Each path As String In pathsNotFound
           Log(path)
       Next
   Else
       Log("Loader has been loaded!") 
   End If
 end if

* Reset the dependency trackers
B4X:
BANano.AssetsReset

34. [NEW] In case CSS/JS assets are locale files in your /Files folder (not URLs), you can use the * wildcard:

e.g.

B4X:
BANano.Header.AddJavascriptFile("dayjs-locale*.js")' will load all javascript files starting with dayjs-locale

35. [NEW] Support for the Promise.All, Promise.AllSettled (only newer browsers) and Promise.Race

e.g.
B4X:
Sub BANano_Ready()
   ' All
   Dim ResultsAll() As Object 
   Dim pAll1 As BANanoPromise = 3 'ignore
   Dim pAll2 As BANanoPromise = 42 'ignore
   Dim pAll3 As BANanoPromise
   pAll3.CallSub(Me, "TheCallDelayed", Array("foo", 100, True))
 
   Dim AllProm As BANanoPromise = BANano.PromiseAll(Array(pAll1, pAll2, pAll3))
   AllProm.Then(ResultsAll)
       ' expected output: Array [3, 42, "foo"]
       Log(ResultsAll)
   AllProm.end
 
   ' AllSettled (not supported in old browsers yet!)
   Dim ResultsAllSettled() As BANanoObject
   Dim pAllSettled1 As BANanoPromise = 3 'ignore
   Dim pAllSettled2 As BANanoPromise
   pAllSettled2.CallSub(Me, "TheCallDelayed", Array(42, 100, False))
   Dim pAllSettled() As BANanoPromise = Array(pAllSettled1, pAllSettled2) 'ignore
   Dim AllSettledProm As BANanoPromise = BANano.PromiseAllSettled(pAllSettled)
   AllSettledProm.Then(ResultsAllSettled)
       ' expected output: fulfilled, rejected
       For i = 0 To ResultsAllSettled.Length - 1
           Log(ResultsAllSettled(i).GetField("status"))         
       Next
   AllSettledProm.end
 
   ' Race
   Dim ResultRace As Object
   Dim pRace1 As BANanoPromise
   pRace1.CallSub(Me, "TheCallDelayed", Array(3, 500, True))
   Dim pRace2 As BANanoPromise
   pRace2.CallSub(Me, "TheCallDelayed", Array("foo", 100, True))
   Dim RaceProm As BANanoPromise = BANano.PromiseRace(Array(pRace1, pRace2))
   RaceProm.Then(ResultRace)
       ' both resolved, but pRace2 is faster so
       ' expected output: foo
       Log(ResultRace)
   RaceProm.end
End Sub

Private Sub TheCallDelayed(ret As Object, ms As Long, DoResolve As Boolean) 'ignore
   BANano.Window.SetTimeout(BANano.CallBack(Me, "ResolveOrReject", Array(ret, DoResolve)), ms)
End Sub

private Sub ResolveOrReject(var As Object, DoResolve As Boolean) 'ignore
   If DoResolve Then
       BANano.ReturnThen(var)
   Else
       BANano.ReturnElse(var)
   End If     
End Sub

36. [NEW] New Initialize4 on BANanoObject

Can be used e.g. to connect a BANanoObject to a JavaScript object, with parameters.
This is basically the .Initialize, but with parameters. It does NOT do a New like the Initialize2 method!

37. Other minor Transpiler fixes and optimisations

Download: https://www.b4x.com/android/forum/t...-abstract-designer-support.99740/#post-627764

Alwaysbusy
 
Last edited:

alwaysbusy

Expert
Licensed User
Longtime User
BANano v4.50

TAKE A BACKUP! <----


This version introduces the BANanoServer b4xlib library, which makes the B4J connection full circle:

The BANanoServer.b4xlib library, source code and demo can be found in the zip in BANano4.50\B4JServerDemo\New System 4.50+\

It add some specific methods to BANano that can only be used when you use this BANanoServer.b4xlib library!

In the B4J IDE there are three new templates classes added :

a. BANanoServer SERVER Class: a template of the server side of a page
b. BANanoServer BROWSER Class: a template of the browser side of a page
c. BANanoServer SHARED Class: a template of a class that can be used both in BANano and B4J.

Use to specify which code is specific for the BANanoServer (B4J) and the BANano Browser part in c.
B4X:
#If #B4J

#Else

#End If

Making changes a this class in B4J debug mode will NOT have any effect on the BANano side until recompiled!

If you want a specific class/module to be transpiled, use the following on top of your class/module:

B4X:
#Region BANano
    ' <-------------- IMPORTANT! This is because we want the non specific B4J code in this module to be transpiled by BANano
#End Region

--------------------------------------------
1. [NEW] a BANano event _ParseEvent(params As Map)

Typically used in a SERVERClass to process an event coming from the browser

B4X:
' event raised to distribute incoming events coming from the BROWSER
public Sub BANano_ParseEvent(params As Map)
    Main.Server.ParseEvent(Me, ws, CacheReport.BANPageID, CacheReport.BANSessionID, params)
End Sub

2. [NEW] a BANano event _Uploaded(status As Int, fileName As String)

Typically used in a SERVERClass to handle an UploadFile

B4X:
' event raised when a file has been uploaded
public Sub BANano_Uploaded(status As Int, fileName As String)
    Log(fileName & " = " & status)
    Select Case status
        Case 200 ' OK
        Case 500 ' was not a POST call
        Case 501 ' file to big
        Case 502 ' file type not allowed
    End Select
End Sub

3. [NEW] BANano.TranspilerOptions.SetStaticFolder() and BANano.StaticFolder (get)

SetStaticFolder has to be used in the AppStart method.
StaticFolder (get) can be used both in B4J as in a BANano class/module.

4. [NEW] BANano.GetPageID

On the Browser side, here you can read the unique page ID (autogenerated)

5. [NEW] UploadFile: Uploads a file from the browser side to the BANanoServer

B4X:
' uploading a file to our server
Sub SKButton1_Click (event As BANanoEvent)
    Dim Response As BANanoObject
    ' get the file object
    Dim theFile As BANanoObject = SKTextBox1.File
    If theFile = Null Then
        BANano.Alert("Please select a file first!")
        Return
    End If
    ' prevent big uploads
    If theFile.GetField("size") > 1024 * 1024 * 5 Then
        BANano.Alert("File is to big!")
        Return
    End If
    ' returns a promise
    Dim prom As BANanoPromise = BANano.UploadFile(theFile)
    prom.Then(Response)
        SKLabel1.Text = "Upload status: " & Response.GetField("status").Result
    prom.Else(Response)
        Log(Response)
    prom.end
End Sub

6. [NEW] New class BananoCacheReport, which returns more info of the cached page.

typical use is on the SERVER side:

B4X:
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
    Log("Connected")
 
    ws = WebSocket1
 
    ' Lets update the cache with this class
    CacheReport = Main.Server.UpdateFromCache(Me, ws)
    Log("PageID: " & CacheReport.BANPageID)
    Log("Comes From Cache:" & CacheReport.ComesFromCache)
    Log("Is a reconnecting socket: " & CacheReport.IsReconnected)
 
    ' We can already send stuff to the browser, using normal B4J jServer code with Future
    Dim fut As Future = ws.RunFunctionWithResult("AddInTheBrowser", Array(20, 30))
    ws.Flush
    Log("BROWSER says sum of 20+30=" & fut.Value)
 
    ' or if no result is expected back
    ws.RunFunction("BROWSERTest", Array("Hello from the SERVER!"))
    ws.Flush
     
    ' IMPORTANT lets tell the browser we are ready to receive call from the browser
    ' Uses the classic WebSocket_Connected and WebSocket_DisConnected events on the browser size
    ' Use Main.Server.SendReady(ws, "ws") if you use the advanced events OnOpen, OnMessage, OnServerReady, ...
    Main.server.SendConnected(ws) 
End Sub

7. [NEW] BANano.B4JCallSubX(Component as Object, Sub as String, Arguments as List)

Similar to CallSub, but with unlimited arguments. Arguments must be passed as an Array.
Can only be used in pure B4J, not in a BANano module!

8. [NEW] BANano.TranspilerOptions.SetSessionMaxInactiveInterval

Sends a heartbeat. Only applicable if a BANanoServer is used.
Should be the same a the BANanoServer.SessionMaxInactiveInterval

9. [NEW] BANanoWebSocket.RunFunctionWithResult

Similar to RunFunction. Returns a BANanoPromise with the result.

10. [NEW] BANanoWebSocket.RunFunction

Runs a B4J function. Pass null to Args if is not needed.

11. [NEW] BANanoWebSocket.IsReconnected

In case of a Reconnecting Websocket, you can check if this was a reconnected session


--------------------------------------------
Used in the BANanoServer library.
In most cases you do not have to use these methods directly but use the BANanoServer methods instead

12. [NEW] BANano.UploadHandlerPath, use BANanoServer.UploadFolder instead

Sets/Gets the folder where Uploads are put

13. [NEW] GetPageHTML. Used internally.


Other changes:
---------------------------------------------

14. [NEW] BANAno.CallBackExtra

Useful where a library you are wrapping needs a function() {} as parameter.

The params are the 'event' params like in the normal CallBack.
The extraParams are extra parameters that the callback method takes, not default to the callback

Example:
B4X:
Sub GetFileFromServer(FileName As String)
      Dim Response As BANanoFetchResponse
    Dim Blob As BANanoObject
 
    ' list (GET is default, and we do not need extra options so we pass Null for the options)
    Dim fetch1 As BANanoFetch
    fetch1.Initialize(FileName, Null)
    fetch1.Then(Response)
        ' we got the response promise, so resolve it to a blob
        fetch1.Return(Response.Blob)
    fetch1.Then(Blob)
        ' we got the blob, read it in a FileReader
        Dim FileReader As BANanoObject
        FileReader.Initialize2("FileReader", Null)
        Dim event As BANanoEvent
        ' the CallBackExtra, which next to the normal event, also we like to pass the filename
        FileReader.SetField("onload", BANano.CallBackExtra(Me, "ReadData", Array(event), Array(FileName)))
        ' get the DataURL
        FileReader.RunMethod("readAsDataURL", Blob)         
    fetch1.End ' always end a fetch with this! 
End Sub

Sub ReadData(event As BANanoEvent, FileName As String) 'ignore
    ' get the data
    Dim Target As BANanoObject = event.OtherField("target")
    Dim DataUrl As String = Target.GetField("result").Result
    Log(FileName)
    log(DataURL) 
End Sub

15. [NEW] BANano.GetFileAsDataURL

Does a Fetch with a resource (e.g. url) and an optional Request options object
Pass null if no request options need to be set

Returns a promise holding the DataURL

B4X:
Dim dataUrl As String
Dim dataUrlProm As BANanoPromise = BANano.GetFileAsDataURL("./assets/B4X.jpg", Null)
dataUrlProm.Then(dataUrl)
         Log(dataUrl)
dataUrlProm.end

16. [NEW] BANano.GetFileAsText

Does a Fetch with a resource (e.g. url) and an optional Request options object
Pass null if no request options need to be set

Returns a promise holding the text

17. [NEW] BANano.GetFileasJSON

Does a Fetch with a resource (e.g. url) and an optional Request options object
Pass null if no request options need to be set

Returns a promise holding the JSON

18. [NEW] BANano.GetFileAsArrayBuffer

Does a Fetch with a resource (e.g. url) and an optional Request options object
Pass null if no request options need to be set

Returns a promise holding the ArrayBuffer

-------------------------------------------------------
New in BANanoPromise

19. [NEW] Promise.NewStart & promise.NewEnd

Make a new Promise with this signature:

B4X:
Dim prom as BANanoPromise
prom.NewStart
   ...
   BANano.ReturnThen(ret)
   ...
   BANano.ReturnElse(ret)
prom.NewEnd
prom.Then(response)

prom.Else(response)

prom.End

Transpiles to:

B4X:
prom = new Promise(function(resolve, reject) {
  ...
  resolve(ret);
  ...
  reject(ret)
});
prom.then(function(response) {

}).else(function(response) {

});

Example:
B4X:
Dim response As String 
Dim prom As BANanoPromise 'ignore
prom.NewStart
        BANano.ReturnThen("Alain")
prom.NewEnd
prom.Then(response)
        Return "Hello " & response & "!" 'ignore
prom.Then(response) 'ignore
        Log(response) ' prints: Hello Alain!
prom.end

20. [NEW] Promise.then now returns a BANanoPromise

---------------------------------------------
BANano.TranspilerOptions:

21. [NEW] BANano.TranspilerOptions.IgnoreB4JLibrary

A B4J library the BANano Transpiler should ignore.

By default, the following are ignored:

BANano
BANanoServer
jCore
jFx
jServer
JavaObject
ABJJWT

22. [NEW] BANano.TranspilerOptions.SetSessionMaxInactiveInterval

Sends a heartbeat. Only applicable if a BANanoServer is used.
Should be the same a the BANanoServer.SessionMaxInactiveInterval

---------------------------------------------
BANanoWebsocket:

23. [NEW] New websocket events.

NOTE:
.Initialize will raise the 'normal' B4J WebSocket events
.InitializeExtended will raise the more advanced websocket events

For the usage of the events, see the demo

OnConnecting(event As BANanoEvent)
OnServerReady()
WebSocket_Connected()
WebSocket_Disconnected(event As BANanoEvent)

24. Other minor Transpiler fixes and optimisations

Download: https://www.b4x.com/android/forum/t...-abstract-designer-support.99740/#post-627764

Alwaysbusy
 
Last edited:

Roberto P.

Well-Known Member
Licensed User
Longtime User
Hi,
where i Find the BANanoCacheReport LIBRARY?!
thank
 

Roberto P.

Well-Known Member
Licensed User
Longtime User
This is part of the main BANano 4.50 library. Have you copied the new version to your Additional Libraries folder?

I have updated all the libraries with Banano 4.5b and it works. thank you
 
Top