67 lines
2.3 KiB
TypeScript
67 lines
2.3 KiB
TypeScript
/**
|
|
* Lazy-loaded offline runtime chunk.
|
|
*
|
|
* Contains Automerge + WASM (~2.5MB) — split from shell.ts so the main
|
|
* shell bundle stays small and doesn't block first paint.
|
|
*/
|
|
|
|
import { RStackHistoryPanel } from "../shared/components/rstack-history-panel";
|
|
import { RSpaceOfflineRuntime } from "../shared/local-first/runtime";
|
|
import { CommunitySync } from "../lib/community-sync";
|
|
import { OfflineStore } from "../lib/offline-store";
|
|
|
|
// Define the history panel component (depends on Automerge)
|
|
RStackHistoryPanel.define();
|
|
|
|
export function initOffline(spaceSlug: string) {
|
|
const runtime = new RSpaceOfflineRuntime(spaceSlug);
|
|
(window as any).__rspaceOfflineRuntime = runtime;
|
|
|
|
// Configure module scope resolution from server-rendered data
|
|
try {
|
|
const scopeJson = document.body?.getAttribute("data-scope-overrides");
|
|
const overrides: Record<string, string> = scopeJson ? JSON.parse(scopeJson) : {};
|
|
const moduleList: Array<{ id: string; scoping?: { defaultScope: string } }> =
|
|
(window as any).__rspaceModuleList || [];
|
|
const scopes: Array<{ id: string; scope: 'global' | 'space' }> = moduleList.map(m => ({
|
|
id: m.id,
|
|
scope: (overrides[m.id] || m.scoping?.defaultScope || 'space') as 'global' | 'space',
|
|
}));
|
|
runtime.setModuleScopes(scopes);
|
|
} catch { /* scope config unavailable — defaults to space-scoped */ }
|
|
|
|
runtime.init().catch((e: unknown) => {
|
|
console.warn("[shell] Offline runtime init failed — REST fallback only:", e);
|
|
});
|
|
|
|
// Flush pending writes before the page unloads
|
|
window.addEventListener("beforeunload", () => {
|
|
runtime.flush();
|
|
});
|
|
|
|
// ── CommunitySync (tab list Automerge sync) ──
|
|
const offlineStore = new OfflineStore();
|
|
const communitySync = new CommunitySync(spaceSlug, offlineStore);
|
|
(window as any).__communitySync = communitySync;
|
|
|
|
(async () => {
|
|
try {
|
|
await offlineStore.open();
|
|
await communitySync.initFromCache();
|
|
} catch (e) {
|
|
console.warn("[shell] CommunitySync cache init failed:", e);
|
|
}
|
|
document.dispatchEvent(new CustomEvent("community-sync-ready", {
|
|
detail: { sync: communitySync, communitySlug: spaceSlug },
|
|
}));
|
|
|
|
const proto = location.protocol === "https:" ? "wss:" : "ws:";
|
|
const wsUrl = `${proto}//${location.host}/ws/${spaceSlug}`;
|
|
communitySync.connect(wsUrl);
|
|
})();
|
|
|
|
window.addEventListener("beforeunload", () => {
|
|
communitySync.saveBeforeUnload();
|
|
});
|
|
}
|