refactor: move internal packages to pkg directory

This commit is contained in:
Prad Nukala 2025-01-06 14:56:16 -05:00
parent c368f2b027
commit afd6b86e68
20 changed files with 111 additions and 106 deletions

View File

@ -5,9 +5,9 @@ package vault
import ( import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
echomiddleware "github.com/labstack/echo/v4/middleware" echomiddleware "github.com/labstack/echo/v4/middleware"
"github.com/onsonr/motr/app/context" motr "github.com/onsonr/motr/pkg/config"
motr "github.com/onsonr/motr/config" "github.com/onsonr/motr/pkg/context"
motrorm "github.com/onsonr/motr/internal/models" motrorm "github.com/onsonr/motr/pkg/models"
) )
type Vault = *echo.Echo type Vault = *echo.Echo

View File

@ -20,9 +20,9 @@ import (
_ "github.com/ncruces/go-sqlite3/driver" _ "github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed" _ "github.com/ncruces/go-sqlite3/embed"
vault "github.com/onsonr/motr/app" 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" sink "github.com/onsonr/motr/internal/sink"
motr "github.com/onsonr/motr/pkg/config"
motrorm "github.com/onsonr/motr/pkg/models"
) )
var ( var (

View File

@ -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 module sonr.net.Motr

View File

@ -8,4 +8,4 @@ sql:
emit_interface: true emit_interface: true
emit_json_tags: true emit_json_tags: true
package: "models" package: "models"
out: "../models" out: "../pkg/models"

View File

@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"github.com/ipfs/boxo/files" "github.com/ipfs/boxo/files"
motr "github.com/onsonr/motr/config" motr "github.com/onsonr/motr/pkg/config"
) )
const SchemaVersion = 1 const SchemaVersion = 1

View File

@ -10,14 +10,14 @@ async function initWasmChannel() {
wasmPort.onmessage = (event) => { wasmPort.onmessage = (event) => {
const { type, data } = event.data; const { type, data } = event.data;
switch (type) { switch (type) {
case 'WASM_READY': case "WASM_READY":
console.log('WASM is ready'); console.log("WASM is ready");
document.dispatchEvent(new CustomEvent('wasm-ready')); document.dispatchEvent(new CustomEvent("wasm-ready"));
break; break;
case 'RESPONSE': case "RESPONSE":
handleWasmResponse(data); handleWasmResponse(data);
break; break;
case 'SYNC_COMPLETE': case "SYNC_COMPLETE":
handleSyncComplete(data); handleSyncComplete(data);
break; break;
} }
@ -28,9 +28,9 @@ async function initWasmChannel() {
async function init() { async function init() {
try { try {
// Register service worker // Register service worker
if ('serviceWorker' in navigator) { if ("serviceWorker" in navigator) {
const registration = await navigator.serviceWorker.register('./sw.js'); const registration = await navigator.serviceWorker.register("./sw.js");
console.log('ServiceWorker registered'); console.log("ServiceWorker registered");
// Wait for the service worker to be ready // Wait for the service worker to be ready
await navigator.serviceWorker.ready; await navigator.serviceWorker.ready;
@ -39,32 +39,35 @@ async function init() {
await initWasmChannel(); await initWasmChannel();
// Send the MessageChannel port to the service worker // Send the MessageChannel port to the service worker
navigator.serviceWorker.controller.postMessage({ navigator.serviceWorker.controller.postMessage(
type: 'PORT_INITIALIZATION', {
port: wasmChannel.port2 type: "PORT_INITIALIZATION",
}, [wasmChannel.port2]); port: wasmChannel.port2,
},
[wasmChannel.port2],
);
// Register for periodic sync if available // Register for periodic sync if available
if ('periodicSync' in registration) { if ("periodicSync" in registration) {
try { try {
await registration.periodicSync.register('wasm-sync', { await registration.periodicSync.register("wasm-sync", {
minInterval: 24 * 60 * 60 * 1000 // 24 hours minInterval: 24 * 60 * 60 * 1000, // 24 hours
}); });
} catch (error) { } 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 // Initialize HTMX with custom config
htmx.config.withCredentials = true; htmx.config.withCredentials = true;
htmx.config.wsReconnectDelay = 'full-jitter'; htmx.config.wsReconnectDelay = "full-jitter";
// Override HTMX's internal request handling // Override HTMX's internal request handling
htmx.config.beforeRequest = function (config) { htmx.config.beforeRequest = function (config) {
// Add request ID for tracking // Add request ID for tracking
const requestId = 'req_' + Date.now(); const requestId = "req_" + Date.now();
config.headers['X-Wasm-Request-ID'] = requestId; config.headers["X-Wasm-Request-ID"] = requestId;
// If offline, handle through service worker // If offline, handle through service worker
if (!navigator.onLine) { if (!navigator.onLine) {
@ -80,11 +83,10 @@ async function init() {
// Handle HTMX errors // Handle HTMX errors
htmx.config.errorHandler = function (error) { htmx.config.errorHandler = function (error) {
console.error('HTMX Error:', error); console.error("HTMX Error:", error);
}; };
} catch (error) { } catch (error) {
console.error('Initialization failed:', error); console.error("Initialization failed:", error);
} }
} }
@ -92,7 +94,9 @@ function handleWasmResponse(data) {
const { requestId, response } = data; const { requestId, response } = data;
// Process the WASM response // Process the WASM response
// This might update the UI or trigger HTMX swaps // 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) { if (targetElement) {
htmx.process(targetElement); htmx.process(targetElement);
} }
@ -102,51 +106,53 @@ function handleSyncComplete(data) {
const { url } = data; const { url } = data;
// Handle successful sync // Handle successful sync
// Maybe refresh the relevant part of the UI // Maybe refresh the relevant part of the UI
htmx.trigger('body', 'sync:complete', { url }); htmx.trigger("body", "sync:complete", { url });
} }
// Handle offline status changes // Handle offline status changes
window.addEventListener('online', () => { window.addEventListener("online", () => {
document.body.classList.remove('offline'); document.body.classList.remove("offline");
// Trigger sync when back online // Trigger sync when back online
if (wasmPort) { if (wasmPort) {
wasmPort.postMessage({ type: 'SYNC_REQUEST' }); wasmPort.postMessage({ type: "SYNC_REQUEST" });
} }
}); });
window.addEventListener('offline', () => { window.addEventListener("offline", () => {
document.body.classList.add('offline'); document.body.classList.add("offline");
}); });
// Custom event handlers for HTMX // Custom event handlers for HTMX
document.addEventListener('htmx:beforeRequest', (event) => { document.addEventListener("htmx:beforeRequest", (event) => {
const { elt, xhr } = event.detail; const { elt, xhr } = event.detail;
// Add request tracking // Add request tracking
const requestId = xhr.headers['X-Wasm-Request-ID']; const requestId = xhr.headers["X-Wasm-Request-ID"];
elt.setAttribute('data-request-id', requestId); elt.setAttribute("data-request-id", requestId);
}); });
document.addEventListener('htmx:afterRequest', (event) => { document.addEventListener("htmx:afterRequest", (event) => {
const { elt, successful } = event.detail; const { elt, successful } = event.detail;
if (successful) { if (successful) {
elt.removeAttribute('data-request-id'); elt.removeAttribute("data-request-id");
} }
}); });
// Initialize everything when the page loads // Initialize everything when the page loads
document.addEventListener('DOMContentLoaded', init); document.addEventListener("DOMContentLoaded", init);
// Export functions that might be needed by WASM // Export functions that might be needed by WASM
window.wasmBridge = { window.wasmBridge = {
triggerUIUpdate: function (selector, content) { triggerUIUpdate: function (selector, content) {
const target = document.querySelector(selector); const target = document.querySelector(selector);
if (target) { 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 // Implement notification system
console.log(`${type}: ${message}`); console.log(`${type}: ${message}`);
} },
}; };

View File

@ -1,8 +1,8 @@
// Cache names for different types of resources // Cache names for different types of resources
const CACHE_NAMES = { const CACHE_NAMES = {
wasm: 'wasm-cache-v1', wasm: "wasm-cache-v1",
static: 'static-cache-v1', static: "static-cache-v1",
dynamic: 'dynamic-cache-v1' dynamic: "dynamic-cache-v1",
}; };
// Import required scripts // Import required scripts
@ -12,7 +12,9 @@ importScripts(
); );
// Initialize WASM HTTP listener // 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 // MessageChannel port for WASM communication
let wasmPort; let wasmPort;
@ -21,8 +23,8 @@ let wasmPort;
let requestQueue = new Map(); let requestQueue = new Map();
// Setup message channel handler // Setup message channel handler
self.addEventListener('message', async (event) => { self.addEventListener("message", async (event) => {
if (event.data.type === 'PORT_INITIALIZATION') { if (event.data.type === "PORT_INITIALIZATION") {
wasmPort = event.data.port; wasmPort = event.data.port;
setupWasmCommunication(); setupWasmCommunication();
} }
@ -33,17 +35,17 @@ function setupWasmCommunication() {
const { type, data } = event.data; const { type, data } = event.data;
switch (type) { switch (type) {
case 'WASM_REQUEST': case "WASM_REQUEST":
handleWasmRequest(data); handleWasmRequest(data);
break; break;
case 'SYNC_REQUEST': case "SYNC_REQUEST":
processSyncQueue(); processSyncQueue();
break; break;
} }
}; };
// Notify that WASM is ready // Notify that WASM is ready
wasmPort.postMessage({ type: 'WASM_READY' }); wasmPort.postMessage({ type: "WASM_READY" });
} }
// Enhanced install event // Enhanced install event
@ -52,13 +54,15 @@ self.addEventListener("install", (event) => {
Promise.all([ Promise.all([
skipWaiting(), skipWaiting(),
// Cache WASM binary and essential resources // Cache WASM binary and essential resources
caches.open(CACHE_NAMES.wasm).then(cache => caches
.open(CACHE_NAMES.wasm)
.then((cache) =>
cache.addAll([ cache.addAll([
'https://cdn.sonr.id/wasm/app.wasm', "https://cdn.sonr.id/wasm/app.wasm",
'https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js' "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([ Promise.all([
clients.claim(), clients.claim(),
// Clean up old caches // Clean up old caches
caches.keys().then(keys => caches.keys().then((keys) =>
Promise.all( Promise.all(
keys.map(key => { keys.map((key) => {
if (!Object.values(CACHE_NAMES).includes(key)) { if (!Object.values(CACHE_NAMES).includes(key)) {
return caches.delete(key); return caches.delete(key);
} }
}) }),
) ),
) ),
]) ]),
); );
}); });
// Intercept fetch events // Intercept fetch events
self.addEventListener('fetch', (event) => { self.addEventListener("fetch", (event) => {
const request = event.request; const request = event.request;
// Handle API requests differently from static resources // Handle API requests differently from static resources
if (request.url.includes('/api/')) { if (request.url.includes("/api/")) {
event.respondWith(handleApiRequest(request)); event.respondWith(handleApiRequest(request));
} else { } else {
event.respondWith(handleStaticRequest(request)); event.respondWith(handleStaticRequest(request));
@ -113,22 +117,16 @@ async function handleApiRequest(request) {
} }
// Return offline response // Return offline response
return new Response( return new Response(JSON.stringify({ error: "Currently offline" }), {
JSON.stringify({ error: 'Currently offline' }),
{
status: 503, status: 503,
headers: { 'Content-Type': 'application/json' } headers: { "Content-Type": "application/json" },
} });
);
} catch (error) { } catch (error) {
await queueRequest(request); await queueRequest(request);
return new Response( return new Response(JSON.stringify({ error: "Request failed" }), {
JSON.stringify({ error: 'Request failed' }),
{
status: 500, status: 500,
headers: { 'Content-Type': 'application/json' } headers: { "Content-Type": "application/json" },
} });
);
} }
} }
@ -151,8 +149,8 @@ async function handleStaticRequest(request) {
return response; return response;
} catch (error) { } catch (error) {
// Return offline page for navigation requests // Return offline page for navigation requests
if (request.mode === 'navigate') { if (request.mode === "navigate") {
return caches.match('/offline.html'); return caches.match("/offline.html");
} }
throw error; throw error;
} }
@ -169,15 +167,15 @@ async function processWasmResponse(request, response) {
// Notify client through message channel // Notify client through message channel
if (wasmPort) { if (wasmPort) {
wasmPort.postMessage({ wasmPort.postMessage({
type: 'RESPONSE', type: "RESPONSE",
requestId: request.headers.get('X-Wasm-Request-ID'), requestId: request.headers.get("X-Wasm-Request-ID"),
response: processedResponse response: processedResponse,
}); });
} }
return processedResponse; return processedResponse;
} catch (error) { } catch (error) {
console.error('WASM processing error:', error); console.error("WASM processing error:", error);
return response; return response;
} }
} }
@ -188,9 +186,9 @@ async function queueRequest(request) {
// Register for background sync // Register for background sync
try { try {
await self.registration.sync.register('wasm-sync'); await self.registration.sync.register("wasm-sync");
} catch (error) { } 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, method: request.method,
headers, headers,
body: await request.text(), body: await request.text(),
timestamp: Date.now() timestamp: Date.now(),
}; };
} }
// Handle background sync // Handle background sync
self.addEventListener('sync', (event) => { self.addEventListener("sync", (event) => {
if (event.tag === 'wasm-sync') { if (event.tag === "wasm-sync") {
event.waitUntil(processSyncQueue()); event.waitUntil(processSyncQueue());
} }
}); });
@ -221,11 +219,13 @@ async function processSyncQueue() {
for (const serializedRequest of requests) { for (const serializedRequest of requests) {
try { try {
const response = await fetch(new Request(serializedRequest.url, { const response = await fetch(
new Request(serializedRequest.url, {
method: serializedRequest.method, method: serializedRequest.method,
headers: serializedRequest.headers, headers: serializedRequest.headers,
body: serializedRequest.body body: serializedRequest.body,
})); }),
);
if (response.ok) { if (response.ok) {
requestQueue.delete(serializedRequest.url); requestQueue.delete(serializedRequest.url);
@ -233,13 +233,13 @@ async function processSyncQueue() {
// Notify client of successful sync // Notify client of successful sync
if (wasmPort) { if (wasmPort) {
wasmPort.postMessage({ wasmPort.postMessage({
type: 'SYNC_COMPLETE', type: "SYNC_COMPLETE",
url: serializedRequest.url url: serializedRequest.url,
}); });
} }
} }
} catch (error) { } 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 // Handle periodic sync if available
self.addEventListener('periodicsync', (event) => { self.addEventListener("periodicsync", (event) => {
if (event.tag === 'wasm-sync') { if (event.tag === "wasm-sync") {
event.waitUntil(processSyncQueue()); event.waitUntil(processSyncQueue());
} }
}); });