diff --git a/app/app.go b/app/app.go index 37dd6d2..20f58f0 100644 --- a/app/app.go +++ b/app/app.go @@ -5,9 +5,9 @@ package vault import ( "github.com/labstack/echo/v4" echomiddleware "github.com/labstack/echo/v4/middleware" - "github.com/onsonr/motr/app/context" - motr "github.com/onsonr/motr/config" - motrorm "github.com/onsonr/motr/internal/models" + motr "github.com/onsonr/motr/pkg/config" + "github.com/onsonr/motr/pkg/context" + motrorm "github.com/onsonr/motr/pkg/models" ) type Vault = *echo.Echo diff --git a/cmd/vault/main.go b/cmd/vault/main.go index ebc7328..8dc5da5 100644 --- a/cmd/vault/main.go +++ b/cmd/vault/main.go @@ -20,9 +20,9 @@ import ( _ "github.com/ncruces/go-sqlite3/driver" _ "github.com/ncruces/go-sqlite3/embed" vault "github.com/onsonr/motr/app" - motr "github.com/onsonr/motr/config" - motrorm "github.com/onsonr/motr/internal/models" sink "github.com/onsonr/motr/internal/sink" + motr "github.com/onsonr/motr/pkg/config" + motrorm "github.com/onsonr/motr/pkg/models" ) var ( diff --git a/internal/pkl/App.pkl b/internal/pkl/App.pkl index 1f7b226..413d7ce 100644 --- a/internal/pkl/App.pkl +++ b/internal/pkl/App.pkl @@ -1,4 +1,4 @@ -@go.Package { name = "github.com/onsonr/motr/config" } +@go.Package { name = "github.com/onsonr/motr/pkg/config" } module sonr.net.Motr diff --git a/internal/sqlc.yaml b/internal/sqlc.yaml index 1703fbd..29ad5d3 100644 --- a/internal/sqlc.yaml +++ b/internal/sqlc.yaml @@ -8,4 +8,4 @@ sql: emit_interface: true emit_json_tags: true package: "models" - out: "../models" + out: "../pkg/models" diff --git a/config/Config.pkl.go b/pkg/config/Config.pkl.go similarity index 100% rename from config/Config.pkl.go rename to pkg/config/Config.pkl.go diff --git a/config/Environment.pkl.go b/pkg/config/Environment.pkl.go similarity index 100% rename from config/Environment.pkl.go rename to pkg/config/Environment.pkl.go diff --git a/config/Motr.pkl.go b/pkg/config/Motr.pkl.go similarity index 100% rename from config/Motr.pkl.go rename to pkg/config/Motr.pkl.go diff --git a/config/Schema.pkl.go b/pkg/config/Schema.pkl.go similarity index 100% rename from config/Schema.pkl.go rename to pkg/config/Schema.pkl.go diff --git a/config/init.pkl.go b/pkg/config/init.pkl.go similarity index 100% rename from config/init.pkl.go rename to pkg/config/init.pkl.go diff --git a/app/context/wasm.go b/pkg/context/wasm.go similarity index 100% rename from app/context/wasm.go rename to pkg/context/wasm.go diff --git a/embed/codec.go b/pkg/embed/codec.go similarity index 96% rename from embed/codec.go rename to pkg/embed/codec.go index 0144c05..21f9dc2 100644 --- a/embed/codec.go +++ b/pkg/embed/codec.go @@ -4,7 +4,7 @@ import ( "encoding/json" "github.com/ipfs/boxo/files" - motr "github.com/onsonr/motr/config" + motr "github.com/onsonr/motr/pkg/config" ) const SchemaVersion = 1 diff --git a/embed/index.html b/pkg/embed/index.html similarity index 100% rename from embed/index.html rename to pkg/embed/index.html diff --git a/embed/main.js b/pkg/embed/main.js similarity index 59% rename from embed/main.js rename to pkg/embed/main.js index 480d263..b737ac8 100644 --- a/embed/main.js +++ b/pkg/embed/main.js @@ -10,14 +10,14 @@ async function initWasmChannel() { wasmPort.onmessage = (event) => { const { type, data } = event.data; switch (type) { - case 'WASM_READY': - console.log('WASM is ready'); - document.dispatchEvent(new CustomEvent('wasm-ready')); + case "WASM_READY": + console.log("WASM is ready"); + document.dispatchEvent(new CustomEvent("wasm-ready")); break; - case 'RESPONSE': + case "RESPONSE": handleWasmResponse(data); break; - case 'SYNC_COMPLETE': + case "SYNC_COMPLETE": handleSyncComplete(data); break; } @@ -28,9 +28,9 @@ async function initWasmChannel() { async function init() { try { // Register service worker - if ('serviceWorker' in navigator) { - const registration = await navigator.serviceWorker.register('./sw.js'); - console.log('ServiceWorker registered'); + if ("serviceWorker" in navigator) { + const registration = await navigator.serviceWorker.register("./sw.js"); + console.log("ServiceWorker registered"); // Wait for the service worker to be ready await navigator.serviceWorker.ready; @@ -39,32 +39,35 @@ async function init() { await initWasmChannel(); // Send the MessageChannel port to the service worker - navigator.serviceWorker.controller.postMessage({ - type: 'PORT_INITIALIZATION', - port: wasmChannel.port2 - }, [wasmChannel.port2]); + navigator.serviceWorker.controller.postMessage( + { + type: "PORT_INITIALIZATION", + port: wasmChannel.port2, + }, + [wasmChannel.port2], + ); // Register for periodic sync if available - if ('periodicSync' in registration) { + if ("periodicSync" in registration) { try { - await registration.periodicSync.register('wasm-sync', { - minInterval: 24 * 60 * 60 * 1000 // 24 hours + await registration.periodicSync.register("wasm-sync", { + minInterval: 24 * 60 * 60 * 1000, // 24 hours }); } catch (error) { - console.log('Periodic sync could not be registered:', error); + console.log("Periodic sync could not be registered:", error); } } } // Initialize HTMX with custom config htmx.config.withCredentials = true; - htmx.config.wsReconnectDelay = 'full-jitter'; + htmx.config.wsReconnectDelay = "full-jitter"; // Override HTMX's internal request handling htmx.config.beforeRequest = function (config) { // Add request ID for tracking - const requestId = 'req_' + Date.now(); - config.headers['X-Wasm-Request-ID'] = requestId; + const requestId = "req_" + Date.now(); + config.headers["X-Wasm-Request-ID"] = requestId; // If offline, handle through service worker if (!navigator.onLine) { @@ -80,11 +83,10 @@ async function init() { // Handle HTMX errors htmx.config.errorHandler = function (error) { - console.error('HTMX Error:', error); + console.error("HTMX Error:", error); }; - } catch (error) { - console.error('Initialization failed:', error); + console.error("Initialization failed:", error); } } @@ -92,7 +94,9 @@ function handleWasmResponse(data) { const { requestId, response } = data; // Process the WASM response // This might update the UI or trigger HTMX swaps - const targetElement = document.querySelector(`[data-request-id="${requestId}"]`); + const targetElement = document.querySelector( + `[data-request-id="${requestId}"]`, + ); if (targetElement) { htmx.process(targetElement); } @@ -102,51 +106,53 @@ function handleSyncComplete(data) { const { url } = data; // Handle successful sync // Maybe refresh the relevant part of the UI - htmx.trigger('body', 'sync:complete', { url }); + htmx.trigger("body", "sync:complete", { url }); } // Handle offline status changes -window.addEventListener('online', () => { - document.body.classList.remove('offline'); +window.addEventListener("online", () => { + document.body.classList.remove("offline"); // Trigger sync when back online if (wasmPort) { - wasmPort.postMessage({ type: 'SYNC_REQUEST' }); + wasmPort.postMessage({ type: "SYNC_REQUEST" }); } }); -window.addEventListener('offline', () => { - document.body.classList.add('offline'); +window.addEventListener("offline", () => { + document.body.classList.add("offline"); }); // Custom event handlers for HTMX -document.addEventListener('htmx:beforeRequest', (event) => { +document.addEventListener("htmx:beforeRequest", (event) => { const { elt, xhr } = event.detail; // Add request tracking - const requestId = xhr.headers['X-Wasm-Request-ID']; - elt.setAttribute('data-request-id', requestId); + const requestId = xhr.headers["X-Wasm-Request-ID"]; + elt.setAttribute("data-request-id", requestId); }); -document.addEventListener('htmx:afterRequest', (event) => { +document.addEventListener("htmx:afterRequest", (event) => { const { elt, successful } = event.detail; if (successful) { - elt.removeAttribute('data-request-id'); + elt.removeAttribute("data-request-id"); } }); // Initialize everything when the page loads -document.addEventListener('DOMContentLoaded', init); +document.addEventListener("DOMContentLoaded", init); // Export functions that might be needed by WASM window.wasmBridge = { triggerUIUpdate: function (selector, content) { const target = document.querySelector(selector); if (target) { - htmx.process(htmx.parse(content).forEach(node => target.appendChild(node))); + htmx.process( + htmx.parse(content).forEach((node) => target.appendChild(node)), + ); } }, - showNotification: function (message, type = 'info') { + showNotification: function (message, type = "info") { // Implement notification system console.log(`${type}: ${message}`); - } + }, }; diff --git a/embed/sw.js b/pkg/embed/sw.js similarity index 67% rename from embed/sw.js rename to pkg/embed/sw.js index e149065..072d469 100644 --- a/embed/sw.js +++ b/pkg/embed/sw.js @@ -1,8 +1,8 @@ // Cache names for different types of resources const CACHE_NAMES = { - wasm: 'wasm-cache-v1', - static: 'static-cache-v1', - dynamic: 'dynamic-cache-v1' + wasm: "wasm-cache-v1", + static: "static-cache-v1", + dynamic: "dynamic-cache-v1", }; // Import required scripts @@ -12,7 +12,9 @@ importScripts( ); // Initialize WASM HTTP listener -const wasmInstance = registerWasmHTTPListener("https://cdn.sonr.id/wasm/app.wasm"); +const wasmInstance = registerWasmHTTPListener( + "https://cdn.sonr.id/wasm/app.wasm", +); // MessageChannel port for WASM communication let wasmPort; @@ -21,8 +23,8 @@ let wasmPort; let requestQueue = new Map(); // Setup message channel handler -self.addEventListener('message', async (event) => { - if (event.data.type === 'PORT_INITIALIZATION') { +self.addEventListener("message", async (event) => { + if (event.data.type === "PORT_INITIALIZATION") { wasmPort = event.data.port; setupWasmCommunication(); } @@ -33,17 +35,17 @@ function setupWasmCommunication() { const { type, data } = event.data; switch (type) { - case 'WASM_REQUEST': + case "WASM_REQUEST": handleWasmRequest(data); break; - case 'SYNC_REQUEST': + case "SYNC_REQUEST": processSyncQueue(); break; } }; // Notify that WASM is ready - wasmPort.postMessage({ type: 'WASM_READY' }); + wasmPort.postMessage({ type: "WASM_READY" }); } // Enhanced install event @@ -52,13 +54,15 @@ self.addEventListener("install", (event) => { Promise.all([ skipWaiting(), // Cache WASM binary and essential resources - caches.open(CACHE_NAMES.wasm).then(cache => - cache.addAll([ - 'https://cdn.sonr.id/wasm/app.wasm', - 'https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js' - ]) - ) - ]) + caches + .open(CACHE_NAMES.wasm) + .then((cache) => + cache.addAll([ + "https://cdn.sonr.id/wasm/app.wasm", + "https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js", + ]), + ), + ]), ); }); @@ -68,25 +72,25 @@ self.addEventListener("activate", (event) => { Promise.all([ clients.claim(), // Clean up old caches - caches.keys().then(keys => + caches.keys().then((keys) => Promise.all( - keys.map(key => { + keys.map((key) => { if (!Object.values(CACHE_NAMES).includes(key)) { return caches.delete(key); } - }) - ) - ) - ]) + }), + ), + ), + ]), ); }); // Intercept fetch events -self.addEventListener('fetch', (event) => { +self.addEventListener("fetch", (event) => { const request = event.request; // Handle API requests differently from static resources - if (request.url.includes('/api/')) { + if (request.url.includes("/api/")) { event.respondWith(handleApiRequest(request)); } else { event.respondWith(handleStaticRequest(request)); @@ -113,22 +117,16 @@ async function handleApiRequest(request) { } // Return offline response - return new Response( - JSON.stringify({ error: 'Currently offline' }), - { - status: 503, - headers: { 'Content-Type': 'application/json' } - } - ); + return new Response(JSON.stringify({ error: "Currently offline" }), { + status: 503, + headers: { "Content-Type": "application/json" }, + }); } catch (error) { await queueRequest(request); - return new Response( - JSON.stringify({ error: 'Request failed' }), - { - status: 500, - headers: { 'Content-Type': 'application/json' } - } - ); + return new Response(JSON.stringify({ error: "Request failed" }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); } } @@ -151,8 +149,8 @@ async function handleStaticRequest(request) { return response; } catch (error) { // Return offline page for navigation requests - if (request.mode === 'navigate') { - return caches.match('/offline.html'); + if (request.mode === "navigate") { + return caches.match("/offline.html"); } throw error; } @@ -169,15 +167,15 @@ async function processWasmResponse(request, response) { // Notify client through message channel if (wasmPort) { wasmPort.postMessage({ - type: 'RESPONSE', - requestId: request.headers.get('X-Wasm-Request-ID'), - response: processedResponse + type: "RESPONSE", + requestId: request.headers.get("X-Wasm-Request-ID"), + response: processedResponse, }); } return processedResponse; } catch (error) { - console.error('WASM processing error:', error); + console.error("WASM processing error:", error); return response; } } @@ -188,9 +186,9 @@ async function queueRequest(request) { // Register for background sync try { - await self.registration.sync.register('wasm-sync'); + await self.registration.sync.register("wasm-sync"); } catch (error) { - console.error('Sync registration failed:', error); + console.error("Sync registration failed:", error); } } @@ -205,13 +203,13 @@ async function serializeRequest(request) { method: request.method, headers, body: await request.text(), - timestamp: Date.now() + timestamp: Date.now(), }; } // Handle background sync -self.addEventListener('sync', (event) => { - if (event.tag === 'wasm-sync') { +self.addEventListener("sync", (event) => { + if (event.tag === "wasm-sync") { event.waitUntil(processSyncQueue()); } }); @@ -221,11 +219,13 @@ async function processSyncQueue() { for (const serializedRequest of requests) { try { - const response = await fetch(new Request(serializedRequest.url, { - method: serializedRequest.method, - headers: serializedRequest.headers, - body: serializedRequest.body - })); + const response = await fetch( + new Request(serializedRequest.url, { + method: serializedRequest.method, + headers: serializedRequest.headers, + body: serializedRequest.body, + }), + ); if (response.ok) { requestQueue.delete(serializedRequest.url); @@ -233,13 +233,13 @@ async function processSyncQueue() { // Notify client of successful sync if (wasmPort) { wasmPort.postMessage({ - type: 'SYNC_COMPLETE', - url: serializedRequest.url + type: "SYNC_COMPLETE", + url: serializedRequest.url, }); } } } catch (error) { - console.error('Sync failed for request:', error); + console.error("Sync failed for request:", error); } } } @@ -250,9 +250,8 @@ self.addEventListener("canmakepayment", function (e) { }); // Handle periodic sync if available -self.addEventListener('periodicsync', (event) => { - if (event.tag === 'wasm-sync') { +self.addEventListener("periodicsync", (event) => { + if (event.tag === "wasm-sync") { event.waitUntil(processSyncQueue()); } }); - diff --git a/embed/utils.go b/pkg/embed/utils.go similarity index 100% rename from embed/utils.go rename to pkg/embed/utils.go diff --git a/embed/webworker.go b/pkg/embed/webworker.go similarity index 100% rename from embed/webworker.go rename to pkg/embed/webworker.go diff --git a/models/db.go b/pkg/models/db.go similarity index 100% rename from models/db.go rename to pkg/models/db.go diff --git a/models/models.go b/pkg/models/models.go similarity index 100% rename from models/models.go rename to pkg/models/models.go diff --git a/models/querier.go b/pkg/models/querier.go similarity index 100% rename from models/querier.go rename to pkg/models/querier.go diff --git a/models/query.sql.go b/pkg/models/query.sql.go similarity index 100% rename from models/query.sql.go rename to pkg/models/query.sql.go