Move static outside HTML. Start work on TypeScript bundle

It's not strictly HTML, so that's just correct.

This is just worth doing while building the new TypeScript bundle
This commit is contained in:
Eli Ribble 2026-03-21 03:06:59 +00:00
parent 976a29b7d7
commit 31947c848a
No known key found for this signature in database
53 changed files with 7100 additions and 73 deletions

3
.gitignore vendored
View file

@ -3,12 +3,11 @@ cmd/geocode-test/geocode-test
cmd/passwordgen/passwordgen
districts/
flogo.log
html/static/css/bootstrap.css
html/static/css/bootstrap.css.map
nidus-sync
nidus-sync.log
result
stadia/cmd/bulk-geocode/bulk-geocode
stadia/cmd/reverse-geocode/reverse-geocode
stadia/cmd/structured-geocode/structured-geocode
static/gen/
tmp/

View file

@ -93,10 +93,11 @@ esbuild ts/main.ts --bundle --outfile=html/static/bundle.js --format=iife --mini
```
The only page that works right now is `https://sync.nidus.cloud/template-test`
### watchexec
For iterating on styles
```
watchexec -e scss sass scss/custom.scss:html/static/css/bootstrap.css
watchexec -e scss sass scss/custom.scss:static/gen/css/bootstrap.css
```

View file

@ -12,10 +12,14 @@ pkgs.buildGoModule rec {
vendorHash = "sha256-zXjryPAJYpc80cqYtrcp//i6OQi5V5QwhaKQYYfrlL8=";
buildInputs = [ pkgs.proj ];
nativeBuildInputs = [ pkgs.pkg-config pkgs.dart-sass ];
nativeBuildInputs = [
pkgs.pkg-config
pkgs.dart-sass
pkgs.esbuild
];
preBuild = ''
# Compile SCSS
SASS_SRC_DIR="./scss"
CSS_OUTPUT_DIR="./html/static/css/"
@ -23,5 +27,26 @@ pkgs.buildGoModule rec {
echo "Compiling $SASS_SRC_DIR/custom.scss to $CSS_OUTPUT_DIR/bootstrap.css..."
sass --style=compressed --trace "$SASS_SRC_DIR/custom.scss":"$CSS_OUTPUT_DIR/bootstrap.css"
# Bundle TypeScript
JS_OUTPUT_DIR="./html/static/gen/js/"
mkdir -p "$JS_OUTPUT_DIR"
echo "Bundling TypeScript..."
esbuild ts/main.ts --bundle --minify --outfile="$JS_OUTPUT_DIR/bundle.js"
# Generate hash and rename bundle
BUNDLE_HASH=$(sha256sum "$JS_OUTPUT_DIR/bundle.js" | cut -c1-12)
mv "$JS_OUTPUT_DIR/bundle.js" "$JS_OUTPUT_DIR/bundle.$BUNDLE_HASH.js"
# Generate gen.go with bundle path
cat > gen.go <<EOF
package main
// Generated by Nix build - do not edit manually
const JsBundlePath = "/static/js/bundel.$BUNDLE_HASH.js"
EOF
echo "Generated JS bundle with hash: $BUNDLE_HASH"
'';
}

View file

@ -11,6 +11,7 @@ import (
"time"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/static"
"github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
)
@ -19,6 +20,15 @@ import (
// static files from a http.FileSystem.
var startedTime time.Time = time.Now()
var localFS http.Dir
func AddStaticRoute(r chi.Router, path string) {
if localFS == "" {
localFS = http.Dir("./static")
}
fileServer(r, "/static", localFS, static.EmbeddedStaticFS, "static")
}
func fileServer(r chi.Router, path string, root http.FileSystem, embeddedFS embed.FS, embeddedPath string) {
if strings.ContainsAny(path, "{}*") {
panic("FileServer does not permit any URL parameters.")

View file

@ -12,6 +12,7 @@ import (
"strings"
"time"
"github.com/Gleipnir-Technology/nidus-sync/static"
"github.com/aarondl/opt/null"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
@ -22,6 +23,8 @@ import (
func addFuncMap(t *template.Template) {
funcMap := template.FuncMap{
"bigNumber": bigNumber,
"bundlePathCSS": bundlePathCSS,
"bundlePathJS": bundlePathJS,
"displayUploadStatus": displayUploadStatus,
"displayUploadType": displayUploadType,
"duration": duration,
@ -59,6 +62,12 @@ func bigNumber(n int) string {
return result.String()
}
func bundlePathCSS() string {
return static.BundlePathCSS
}
func bundlePathJS() string {
return static.BundlePathJS
}
func displayUploadStatus(s string) string {
switch s {
case "committed":

View file

@ -1,20 +0,0 @@
package html
import (
"embed"
"net/http"
"github.com/go-chi/chi/v5"
)
//go:embed static/*
var EmbeddedStaticFS embed.FS
var localFS http.Dir
func AddStaticRoute(r chi.Router, path string) {
if localFS == "" {
localFS = http.Dir("./html/static")
}
fileServer(r, "/static", localFS, EmbeddedStaticFS, "static")
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -8,8 +8,7 @@
<link href="/static/css/bootstrap.css" rel="stylesheet" />
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="/static/vendor/css/bootstrap-icons.min.css" />
<!-- favicon -->
<link rel="icon" href="/static/favicon-rmo.ico" type="image/x-icon" />
<link rel="icon" href="/static/ico/favicon-rmo.ico" type="image/x-icon" />
{{ block "extraheader" . }}{{ end }}
<script>
var tooltipByElementId = {};

View file

@ -4,14 +4,12 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ template "title" . }} - Nidus Sync</title>
<!-- Bootstrap CSS -->
<link href="/static/css/bootstrap.css" rel="stylesheet" />
<link href="{{ bundlePathCSS }}" rel="stylesheet" />
<!-- Fontawesome Icons -->
<link rel="stylesheet" href="/static/vendor/css/bootstrap-icons.min.css" />
<!-- favicon -->
<link rel="icon" href="/static/favicon-sync.ico" type="image/x-icon" />
<link rel="icon" href="/static/ico/favicon-sync.ico" type="image/x-icon" />
<script src="/static/js/events.js"></script>
<script defer src="/static/js/alpine-3.15.8-min.js"></script>
<script src="{{ bundlePathJS }}" defer></script>
{{ block "extraheader" . }}{{ end }}
<script>
const USER = {{ .User.AsJSON|json }};

View file

@ -8,8 +8,7 @@
<link href="/static/vendor/css/bootstrap.min.css" rel="stylesheet" />
<!-- Bootstrap Icons -->
<link href="/static/css/bootstrap.css" rel="stylesheet" />
<!-- favicon -->
<link rel="icon" href="/static/favicon-sync.ico" type="image/x-icon" />
<link rel="icon" href="/static/ico/favicon-sync.ico" type="image/x-icon" />
{{ block "extraheader" . }}{{ end }}
{{ if not .Config.IsProductionEnvironment }}
<script src="/.flogo/injector.js"></script>

6
static/gen.go Normal file
View file

@ -0,0 +1,6 @@
package static
// gen.go - checked into git
// This file is overwritten during Nix builds with hashed paths
const BundlePathCSS = "/static/gen/css/bootstrap.css"
const BundlePathJS = "/static/gen/js/bundle.js"

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 191 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Before After
Before After

View file

@ -3,7 +3,7 @@ class AddressDisplay extends HTMLElement {
super();
// Create a shadow DOM
this.attachShadow({mode: "open" });
this.attachShadow({ mode: "open" });
// Initial render
this.render();
@ -99,29 +99,33 @@ class AddressDisplay extends HTMLElement {
// Populate structured fields
// Street Address - combine address, street, housenumber if available
let addressStr = '';
let addressStr = "";
if (context.address) addressStr += context.address.address_number;
if (context.street) {
if (addressStr) addressStr += ' ';
if (addressStr) addressStr += " ";
addressStr += context.street.name;
}
if (addressStr === '') {
addressStr = props.name || props.full_address || '-';
if (addressStr === "") {
addressStr = props.name || props.full_address || "-";
}
this._streetAddress.textContent = addressStr;
// Post Code
this._postCode.textContent = context.postcode.name || '-';
this._postCode.textContent = context.postcode.name || "-";
// District (could be district, locality, or place)
this._district.textContent = context.district.name || context.place.name || context.locality.name || '-';
this._district.textContent =
context.district.name ||
context.place.name ||
context.locality.name ||
"-";
// Region (state, province, etc.)
this._region.textContent = context.region.name || '-';
this._region.textContent = context.region.name || "-";
// Country
this._country.textContent = context.country.name || '-';
this._country.textContent = context.country.name || "-";
}
}
customElements.define('address-display', AddressDisplay);
customElements.define("address-display", AddressDisplay);

View file

@ -10,14 +10,14 @@ function getGeolocation(options) {
const geolocationOptions = options || {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
maximumAge: 0,
};
// Call the geolocation API
navigator.geolocation.getCurrentPosition(
position => resolve(position),
error => reject(error),
geolocationOptions
(position) => resolve(position),
(error) => reject(error),
geolocationOptions,
);
});
}

8
static/static.go Normal file
View file

@ -0,0 +1,8 @@
package static
import (
"embed"
)
//go:embed css gen file ico js vendor
var EmbeddedStaticFS embed.FS

4107
static/vendor/js/bootstrap.bundle.min.js vendored Normal file

File diff suppressed because it is too large Load diff

2892
static/vendor/js/bootstrap.min.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,12 @@
import Alpine from './vendor/alpinejs-3.15.8.js';
// Make Alpine available on window for inline Alpine
window.Alpine = Alpine;
// Wait for DOM to be ready, then initialize Alpine
document.addEventListener("DOMContentLoaded", () => {
Alpine.start();
});
interface GreetingComponent {
message: string;
name: string;
@ -14,6 +21,3 @@ Alpine.data('greeting', (): GreetingComponent => ({
this.message = 'Message updated at ' + new Date().toLocaleTimeString();
}
}));
Alpine.start();