mirror of
https://github.com/onsonr/motr.git
synced 2025-03-10 17:29:10 +00:00
refactor: move internal packages to pkg directory
This commit is contained in:
parent
c368f2b027
commit
afd6b86e68
@ -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
|
||||||
|
@ -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 (
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
@ -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}`);
|
||||||
}
|
},
|
||||||
};
|
};
|
@ -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
|
||||||
cache.addAll([
|
.open(CACHE_NAMES.wasm)
|
||||||
'https://cdn.sonr.id/wasm/app.wasm',
|
.then((cache) =>
|
||||||
'https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js'
|
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([
|
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,
|
||||||
{
|
headers: { "Content-Type": "application/json" },
|
||||||
status: 503,
|
});
|
||||||
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,
|
||||||
{
|
headers: { "Content-Type": "application/json" },
|
||||||
status: 500,
|
});
|
||||||
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(
|
||||||
method: serializedRequest.method,
|
new Request(serializedRequest.url, {
|
||||||
headers: serializedRequest.headers,
|
method: serializedRequest.method,
|
||||||
body: serializedRequest.body
|
headers: serializedRequest.headers,
|
||||||
}));
|
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());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user