github.com/pbberlin/go-pwa@v0.0.0-20220328105622-7c26e0ca1ab8/README.md (about)

     1  # Golang PWA prototype
     2  
     3  <img src="./app-bucket/img/mascot.webp" style="float: left; width:20%; min-width: 140px; max-width: 20%; margin-right:5%; margin-bottom: 2%;"> 
     4  
     5  [![coverage](https://github.com/pbberlin/go-pwa/actions/workflows/codecov.yml/badge.svg)](https://github.com/pbberlin/go-pwa/actions/workflows/codecov.yml)
     6  
     7  Combining the most advanced `golang` techniques  
     8  into a [Google Lighthouse](https://github.com/GoogleChrome/Lighthouse) approved web app
     9  
    10  * HTTP/2
    11  
    12  * Let's encrypt certification
    13  
    14  * Localhost certificate based on [Filipo Valsordas tool](https://github.com/FiloSottile/mkcert)
    15  
    16  * HTTP redirecting or co-existing
    17  
    18  * Content Security Policies (`CSP`)  
    19    against CSRF
    20  
    21  * Consistent versioning of HTML, JS, CSS, IMG,  
    22    _and_ service worker caching
    23  
    24  * Adding a new version at any time by admin http request,  
    25    while older version files remain accessible
    26  
    27  * Make changes to your app at any time,  
    28    without breaking service worker caching
    29  
    30  * Server side gzip precompression of CSS and JS files;  
    31    integrated with version creation
    32  
    33  * Fully developed PWA HTML template
    34  
    35  * Fully developed PWA manifest
    36  
    37  * PWA service worker with `cache-first` for static files
    38  
    39  * Fallback to `/offline.html` for unprecedented user experience
    40  
    41    * PWA service worker register and install
    42  
    43    * PWA service worker pre-caching on install
    44  
    45    * PWA service worker fetch with `cache-first`
    46  
    47  ## Javascript docs
    48  
    49  Finally some comprehensive JS docs
    50  
    51  <https://javascript.info/indexeddb>
    52  
    53  <https://javascript.info/microtask-queue>
    54  
    55  ## Package static
    56  
    57  Preparing and serving static files.  
    58  
    59  The package assumes a directory `./app-bucket`  
    60  containing directories of files by mime-types.  
    61  `/css`, `/js`, `/img`...
    62  
    63  The package also supports typical special files:  
    64  `robots.txt`, `service-worker.js`, `favicon.ico`  
    65  being served under special URIs.
    66  
    67  The package takes care of
    68  
    69  * Execution of templates for special files
    70    * Service worker pre-caching
    71    * `manifest.json` icon files
    72    * Javascript database versioning
    73  
    74  * Mime types by configuration
    75  * HTTP caching by configuration
    76  
    77  * Consistent versioning
    78  
    79  * Gzipping by configuration
    80  * Handler funcs for HTTP request serving
    81  * Registering routes with a http.ServeMux
    82  
    83  Template execution allows custom funcs for arbitrary dynamic preparations.
    84  
    85  A few template execution funcs are provided,  
    86  to prepare Google PWA config files dynamically  
    87  from whatever is in the directories under `./app-bucket`.
    88  
    89  All file preparation logic is put together in the HTTP handle func PrepareStatic(...).
    90  Thus you whenever you changed any static file contents,
    91  call PrepareStatic(), and you get a _consistent_ new version of all static files,
    92  and you force your HTTP client (aka browser) to load
    93  
    94  Todo:
    95  
    96  * Make the config loadable via JSON
    97  * Javascript templating is done in a highly inappropriate way; cannot get idiomatic way to work
    98  * Markdown with some pre-processing is missing
    99  
   100  ## Gorm
   101  
   102  ### Requirements
   103  
   104  * Upsert
   105  
   106  * Associations 1:1, 1:n, m:n
   107  
   108  * Compound unique constraints
   109  
   110  ### Peculiarities
   111  
   112  * Uniqueness indexes should include the deletion date column;  
   113    fields of gorm.Model must explicitly embedded
   114  
   115  * gorm.Model incurs a lot of noise
   116  
   117  * `create` inserts.  
   118    Combined with `onConflictUpdate` on conflict it adds DB specific jargon for upsert/merge. 
   119  
   120  * `save` first updates by primary key.  
   121    If no rows are affected, a `select` is issued. If the record does not exist, it gets inserted.
   122  
   123  * `create` and `save` do not associate with existing unique assocations.  
   124    Instead they fail at creating the same association.  
   125    Then they create an m:n record with the association ID 0;
   126    and without giving any error.
   127  
   128  * Notice with 1:n associations; for example credit cards.  
   129    If we change the ID of an existing entry, but keep the IDs of the CC associations,  
   130    those will be removed from the existing entry and associated with the new one.
   131  
   132  * `Association...Apppend` such as in  
   133    `err = db.Model(&e).Association("Tags").Append(tags)`  
   134    acts the same way
   135  
   136  * We can and should suppress this unhelpful behavior,  
   137    by using `onDuplicateIDUpdate.Omit("Tags").Create(&e)` or `...Create`
   138  
   139  * In addition, we cannot store any additional data into the m:n table  
   140    using the standard funcs