Mit der generierten Vorlage beginnen#
Lade im Entwicklerportal die Vorlage deiner registrierten App herunter. Sie enthält die öffentliche Konfiguration, die Module, den Account-Bereich und den passenden Callback. Die Module müssen lokal zusammen mit deiner App ausgeliefert werden.
Die Konfiguration enthält unter anderem issuer, app, clientId, redirectUri, scope und die aktiven resources. Nach einer Änderung der Registrierung aktualisierst du auch diese Konfiguration.
Ein vollständiges kleines Beispiel#
Lege in deiner App-Oberfläche die Elemente an und binde das Panel-Stylesheet ein:
<link rel="stylesheet" href="./account/panel.css">
<label for="notes">Meine Notiz</label>
<textarea id="notes"></textarea>
<p id="save-status" role="status"></p>
<div id="account"></div>
<script type="module" src="./app.mjs"></script>
In app.mjs ersetzt du den Beispiel-Editor durch Folgendes. Die Datenart notes muss vorher registriert und in der Konfiguration enthalten sein:
import { createJSONAdapter, mountAccount } from './account/sdk.mjs';
import { config } from './account/config.mjs';
const adapter = createJSONAdapter(config);
const notes = document.querySelector('#notes');
const status = document.querySelector('#save-status');
function render() {
notes.value = adapter.get('notes')?.text ?? '';
}
notes.addEventListener('input', () => {
try {
adapter.set('notes', { text: notes.value });
status.textContent = 'Auf diesem Gerät gespeichert.';
} catch {
status.textContent = 'Lokales Speichern fehlgeschlagen. Text bitte sichern.';
}
});
try {
render();
await mountAccount({
root: document.querySelector('#account'),
config,
adapter,
onApply: resource => {
if (resource === 'notes') render();
},
});
} catch {
status.textContent = 'Gespeicherte Daten oder Account-Bereich konnten nicht geladen werden.';
}
set() speichert lokal und meldet eine Änderung an einen eventuell aktiven Sync. Es erzwingt keinen ersten Upload. onApply aktualisiert nach einem Cloud-Import die eigene Oberfläche. Das Beispiel zeigt lokalen Speicherstatus; den Cloud-Status zeigt das Account-Panel.
Ein eigenes Datenformat anbinden#
Statt createJSONAdapter kannst du einen eigenen Adapter an mountAccount übergeben:
| Bestandteil | Aufgabe |
|---|---|
resources |
Liste registrierter Ressourcenschlüssel |
keys |
Zuordnung zu beobachteten localStorage-Schlüsseln |
labels |
Sichtbare Namen unter de und en |
snapshot(resource) |
Aktuellen lokalen Inhalt als JSON-Objekt liefern |
validate(resource, document) |
Cloud-Dokument vor einer Übernahme prüfen |
backup(resource) und backupKey(resource) |
Vorhandenen lokalen Stand sichern |
apply(resource, document) |
Nur die ausgewählte Datenart übernehmen |
Melde lokale Änderungen nach dem Speichern über window.dispatchEvent(new CustomEvent('julianverse:change', { detail: { key } })). key ist ein beobachteter Speicherschlüssel. Lege fest, welche Daten Teil eines Snapshots sind, und schließe Zugangsdaten aus.
Den Sync-Kern direkt verwenden#
Das SDK exportiert außerdem JulianverseSync, IndexedDBStore, SyncError, beginLogin und finishLogin. Der Sync-Kern trennt Konten nach Issuer, Konto-ID und App und hält lokale Arbeitskopien und ausstehende Änderungen in IndexedDB.
attach() meldet an, enable() verlangt die erste Datenquellenwahl, save() speichert lokal, sync() gleicht ab und resolve() behandelt einen Konflikt. Bei einer eigenen Oberfläche musst du Fehler, ausstehende Änderungen und Konflikte selbst sichtbar machen. Die generierte Vorlage enthält bereits ein passendes Panel.
Hosting prüfen#
Verwende die exakte registrierte App- und Callback-Origin. Das Popup darf nicht durch eine unpassende Opener-Policy getrennt werden. Cookies zur Wiederanmeldung können auf externen Domains blockiert sein; biete dann eine erneute Anmeldung an und erhalte lokale Inhalte.
Teste auch abgewiesenen Browserspeicher, widerrufene Zugänge und zwei gleichzeitig geöffnete Tabs. Vermeide einen pauschalen Reset bei Fehlern. Siehe OAuth-Callback und Tokens sowie API-Konfliktverhalten.