Lolly
App openen

Gegevensoverdracht - de bundel lolly-backup

Alles wat een Lolly-gebruiker opbouwt, staat op zijn apparaat - geen account, geen cloud. De gegevensoverdrachtbundel is hoe die waarde verplaatst: exporteer hem op de ene installatie, draag het bestand op elke manier over (USB, AirDrop, e-mail naar jezelf, een netwerkschijf) en importeer hem op een andere. Het bestand is het transport. Het doel kan offline of online zijn. Het maakt geen verschil, want er wordt nooit met een server gepraat.

De twee knoppen die een hele installatie verplaatsen: Mijn gegevens exporteren schrijft één zip, Gegevens importeren leest hem weer in signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBControleer het zelfDownload het ondertekende bestandDe twee knoppen die een hele installatie verplaatsen: Mijn gegevens exporteren schrijft één zip, Gegevens importeren leest hem weer in signed by Lollyvector SVG9 paths~4.9k nodes11 groups56 KBControleer het zelfDownload het ondertekende bestand

Deze pagina is de formaatspecificatie. Voor de doorloop voor de eindgebruiker, zie Vind en herstel je werk → Verhuis je werk naar een ander apparaat. De implementatie is shells/web/src/data-transfer.ts, en tests/data-transfer.test.ts legt het retourcontract vast.

Bereik. Een bundel draagt gebruikersgegevens, geen catalogustools. Catalogustools en catalogusassets worden apart gesynchroniseerd en er wordt aangenomen dat ze al op het doel aanwezig zijn (in het slechtste geval in een hogere versie); tools die een gebruiker zelf maakte, reizen mee binnen profile.json. Importeren installeert of upgradet nooit een catalogustool.

Doelen

De envelop

Een bundel is een gewone .zip. De download wordt genoemd naar de persoon aan wie hij toebehoort - LollyTools-<First>-<Last>-<YYYY-MM-DD>-<n>.zip (bijvoorbeeld LollyTools-Ada-Lovelace-2026-06-26-1.zip) - zodat een Downloads-map vol back-ups leesbaar blijft. De voor- en achternaamdelen komen uit het profiel en worden weggelaten wanneer ze niet zijn ingesteld. Geen profiel geeft LollyTools-2026-06-26-1.zip, en alleen een voornaam geeft LollyTools-Ada-2026-06-26-1.zip. Elk deel wordt gesaneerd tot een bestandsnaamveilig token (Unicode-letters/cijfers blijven behouden, spaties/leestekens worden verwijderd, gelimiteerd tot 32 tekens). <n> is een volgnummer per dag, per apparaat, zodat herhaalde exports op dezelfde dag niet botsen en in volgorde blijven. backupFilename() in shells/web/src/data-transfer.ts bouwt de naam. De inhoud van de zip is identiek, ongeacht de naam. Binnenin:

PadVerplichtInhoud
manifest.jsonjaFormat-id, versies, aantallen en integriteit per onderdeel. Het eerste waar een lezer naar kijkt.
profile.jsonindien ingesteldHet hele me-record van de gebruiker: naam, contactgegevens, profielfotoreferentie en vlaggen, plus mappen, Prullenbak, projectblauwdrukken, gebruikerssjablonen en door de gebruiker gemaakte tools, favorieten, verborgen tools, taal- en emojikeuze. Gelezen via host.profile.
sessions.jsonjaElke opgeslagen sessie: slot, tool-id/versie, label, miniatuur (data-URL) en alle invoergegevens. Gelezen via host.state.
assets.jsonjaMetadata voor elk geüpload asset (afbeeldingen, lettertypen, merktokens, logo's, opgeslagen kopieën van downloads), elk wijzend naar zijn bytes onder assets/blobs/.
assets/blobs/<n>.<ext>per assetDe ruwe assetbytes (afbeeldings- en lettertypebestanden). Onbewerkt (ongecomprimeerd) opgeslagen (al-gecomprimeerde formaten). De extensie is cosmetisch. De MIME in assets.json is leidend.
assets/blobs/<n>.c2paindien aanwezigGeëxtraheerde Content Credentials als exacte binaire bytes, waarnaar wordt verwezen via _credentialFile in het assetrecord. Dit zijn geen ondertekeningssleutels van het apparaat.
design-systems.jsonindien aanwezigDe design systems die op deze installatie zijn gemaakt of toegevoegd, als { active, records }. Gemerged op id bij import; de actieve keuze van de bundel geldt alleen wanneer het doel geen eigen design system heeft.
file-history.jsonoptioneelVersiegebonden assetsnapshots, terminale bestandsoperatierapporten en complete batchmanifesten. Het geschiedenisonderdeel heeft een eigen versie; geleverd door de interne back-upadapter fileHistory van de shell.
revision-history.jsonoptioneel, handmatige back-upsStabiele creatie-ID's, bewaarde checkpoints, miniaturen en doorlopende herstelconcepten. Geleverd door host.state.history.backup waar ondersteund.
file-history/versions/per snapshotEerdere assetbytes en geëxtraheerde credentials, ongeacht of het huidige asset nog bestaat.
file-history/results/per voltooide bewerkingExacte uitvoerbytes. Geen origineel, voor conversie geselecteerd bestand wordt bewaard of meegenomen.
prefs.jsonjaLokale voorkeuren van de gebruiker zelf: theme, sidebarWidth en de activiteitsteller ct-metrics.
lolly.txtjaEen leesbare samenvatting van de bundel (aantallen, profiel, bestandsnaam) voor wie de zip zonder Lolly opent. Opnieuw gegenereerd bij elke export en herkend bij import, dus telt nooit als een overgeslagen onderdeel. Hij wordt na de integriteitskaart geschreven, dus blijft erbuiten.

De bundel is bewust een gewone zip: hij overleeft elk transport intact, en elke unzip-tool kan hem inspecteren.

profile.json is het kleinste onderdeel en het onderdeel dat een lezer in de app als eerste ziet: de gegevens die een producent één keer invult, plus de opt-in die tools toestaat ze te gebruiken.

Het formulier met profielgegevens dat profile.json wordt: naam, contactgegevens en profielfoto signed by Lollyvector SVG15 paths~1.2k nodes30 groups1 image40 KBControleer het zelfDownload het ondertekende bestand

manifest.json

{
  "format": "lolly-backup",
  "formatVersion": 3,
  "minReader": 1,
  "app": "lolly",
  "exportedAt": "2026-06-22T09:30:00.000Z",
  "counts": { "profile": true, "sessions": 2, "userAssets": 4, "prefs": 3, "assetVersions": 1, "fileOperations": 1 },
  "integrity": {
    "profile.json": "sha256-…",
    "sessions.json": "sha256-…",
    "assets.json": "sha256-…",
    "assets/blobs/0.bin": "sha256-…",
    "file-history.json": "sha256-…",
    "file-history/versions/0.bin": "sha256-…",
    "file-history/results/0.bin": "sha256-…",
    "prefs.json": "sha256-…"
  }
}
VeldBetekenis
formatAltijd lolly-backup. Een bestand zonder dit wordt afgewezen als "geen Lolly-back-up".
formatVersionDe lay-out waarmee deze bundel is geschreven. Verhoogd bij elke wijziging in de onderdelenset of vormen. Lezers gebruiken dit niet als grendel.
minReaderDe minimale lezerversie die nodig is om deze bundel veilig te importeren. Dit is het veld waarop lezers grendelen.
appProducerende app-id, voor diagnostiek.
exportedAtISO-tijdstempel waarop de bundel is aangemaakt.
countsWat de schrijver erin heeft gestopt, voor weergave en sanity-check.
integrityOptioneel. Koppelt elk onderdeel behalve manifest.json aan een SRI-achtige sha256-<base64>-digest van de ongecomprimeerde bytes.

Versiebeleid (achterwaartse compatibiliteit)

De scheiding tussen formatVersion en minReader is wat het formaat laat groeien zonder oudere installaties te wezen:

Vuistregel voor auteurs: als elke bestaande lezer nog steeds het juiste zou doen door je toevoeging te negeren, is het additief - verhoog formatVersion, laat minReader staan. Verhoog anders minReader.

Integriteit

Wanneer manifest.integrity aanwezig is, verifieert een lezer de SHA-256 van elk vermeld onderdeel voordat er iets wordt geschreven. Een mismatch ("heeft de integriteitscontrole niet doorstaan") of een ontbrekend onderdeel ("onvolledig") breekt de hele import af - er is geen gedeeltelijk herstel. Dit vangt de corruptie op die een bestandstransport kan veroorzaken (een afgekapte AirDrop, een e-mailgateway die de bijlage opnieuw heeft gecodeerd, een slechte USB-sector).

Integriteit is bewust best-effort: hij wordt alleen geschreven waar Web Crypto beschikbaar is (elke veilige browsercontext en moderne Node), en alleen geverifieerd wanneer zowel de kaart als Web Crypto aanwezig zijn. Een bundel zonder de kaart - bijvoorbeeld een van vóór het bestaan van integriteit - importeert ongewijzigd. "Kan niet verifiëren" wordt nooit behandeld als "corrupt".

Het manifest vermeldt zichzelf niet en ook niet de opnieuw gegenereerde lolly.txt-README. De digests dekken de onderdelen waarvoor het manifest instaat.

Importsemantiek

Importeren is een samenvoeging, nooit alles vervangen:

Opgeslagen sessies koppelen automatisch opnieuw aan hun afbeeldingen: assetreferenties worden bijgehouden op id, en de bridge lost ze opnieuw op nadat de geüploade afbeeldingen zijn hersteld (dat moet toch al, omdat blob:-URL's een herlaad niet overleven).

De importsamenvatting rapporteert { profile, sessions, userAssets, prefs, skipped, failedAssets }. failedAssets telt geüploade assets die niet konden worden hersteld (bijvoorbeeld apparaatopslag vol). Dit staat los van skipped, dat onderdelen telt van een achterwaarts-compatibele nieuwere schrijver die deze build niet herkende. De UI toont skipped ("… · N nieuwere items overgeslagen"), zodat het herstel eerlijk is over wat er is achtergelaten.

Wanneer bestandsgeschiedenis aanwezig is, draagt de samenvatting ook assetVersions, fileOperations en failedHistory. Opslag-uitputting of conflicten met onveranderlijke ID's kunnen een gedeeltelijk herstel veroorzaken; de UI vertelt de gebruiker de bron-back-up te bewaren. Cloudsynchronisatie zet zijn toegepaste revisie niet verder na een gedeeltelijk of niet-ondersteund herstel, zodat de snapshot beschikbaar blijft om opnieuw te proberen. Herstellen is geen enkele transactie over alle profiel-/sessie-/asset-/geschiedenisopslagen heen.

Creatiegeschiedenis (v3)

Handmatige back-ups van een web-host met geschiedeniscapaciteit bevatten revision-history.json met zijn eigen schema { version: 1, documents, revisions, recoveries }. Het draagt de bewaarde ID's, canonieke invoersnapshots, versiestempels, rasterpreviews en aparte schrijversconcepten. De geschiedenisadapter legt huidige sessies en hun koppen vast in één leestransactie; sessions.json gebruikt diezelfde huidige snapshots voor oudere lezers.

Herstel controleert de SHA-256 en bytetellingen van de payload, unieke identiteiten, document/head-relaties, afstamming, tijdstempels, previewtypen en limieten voordat het archief in één transactie wordt vastgelegd. Gecomprimeerde parent-referenties kunnen ontbreken. Bestaand huidig werk wordt nooit stilzwijgend vervangen: wanneer een creatie aan beide kanten bestaat, wordt de kant die niet als huidige wordt aangehouden een beschermd concept. De transferlimiet van 384 MiB van het archief wordt expliciet gecontroleerd, en opslaglimieten worden afgedwongen zonder bewaarde checkpoints af te knippen. De algehele back-up gebruikt nog steeds een in-memory ZIP-implementatie en is geen streamend archief.

De samenvatting voegt revisions en recoveryDrafts toe, waarbij alleen wordt geteld wat deze import heeft toegevoegd, en added, kept, replaced, copies en hidden voor hoe elke creatie is samengevoegd. Een shell zonder deze capaciteit herstelt gewone sessies en meldt het geschiedenisonderdeel als overgeslagen. Native bestandssysteemgeschiedenis blijft niet-ondersteund tot zijn adapter duurzame geschiedenistransacties levert. P2P-gaststatus heeft geen duurzame geschiedenis of herstelarchief.

Persoonlijke snapshotsynchronisatie sluit creatiegeschiedenis expliciet uit. Een snapshot toepassen op een lokaal document met geschiedenis bewaart zijn vorige werktoestand als een apart herstelconcept en maakt het schrijftoken van elke open editor ongeldig. Zijn onveranderlijke checkpoints blijven op het apparaat. Dit beschermt lokale geschiedenis tijdens snapshotvervanging; het merget geen gelijktijdige apparaatgeschiedenissen.

Historische assetverwijzingen worden bewaard, terwijl renderen assets nog steeds oplost via de bestaande bibliotheek van de bestemming. Dit archief garandeert nog geen exacte oude assetbytes of oude tool-renders. Assetversie- en bestandsresultaatbytes blijven reizen via hun eigen bestaande, aparte back-uponderdeel.

Opgeslagen versies en bestandsresultaten (v2)

Het optionele geschiedenisonderdeel bevat { version: 2, assetVersions: [...], operations: [...], batches: [...] }; lezers accepteren ook de eerdere history-v1-vorm zonder batches. Elke snapshot identificeert het stabiele asset-ID en de exacte versie, zijn opslagtijd, bytelengte en hex-SHA-256, plus een assetrecord waarvan _file en optioneel _credentialFile naar binaire onderdelen wijzen. Bewerkingen dragen de oorspronkelijke bestandsfeiten, het verzoek, het rapport, tijdstempels en optioneel resultaat-_file; namen van opslagbackends, OPFS-handles en uitvoeringsleases reizen niet mee. Oudere, alleen-history-v1-lezers weigeren de nieuwe geschiedenisversie vóór import, in plaats van batchlidmaatschap stilzwijgend te laten vallen.

Batchmanifesten leggen elke geselecteerde bron vast vóór verwerking, inclusief nooit gelezen bestanden, geannuleerde leden, mislukte reserveringen van resultaatruimte en onderbroken werk. Elk lid heeft een stabiel bewerkings-ID, bronreferentie/-feiten, gevraagde uitvoernaam en terminaal rapport. Een ongelezen bron heeft verklaarde feiten, geen verzonnen digest. Import valideert lididentiteit en consistentie met elk meegedragen bewerkingsrapport. Batchrapporten blijven beschikbaar wanneer individuele resultaten expliciet zijn verwijderd, maar een ontvangstbewijs impliceert niet dat de uitvoerbytes nog worden opgeslagen.

Oudere lezers accepteren nog steeds de v2-envelop (minReader: 1) en herstellen bekende onderdelen, waarbij niet-ondersteunde geschiedenisonderdelen als overgeslagen worden geteld. Volledig geschiedenisherstel vereist een shell met de fileHistory-adapter; dit is een interne naad van de shell, geen nieuwe, tool-gerichte HostV1-capaciteit. Echt herstel tussen twee apparaten wordt gedekt door de lokale Chromium-poort; geïnstalleerde Tauri-/iOS-/Android-hersteltests blijven apart.

Wat niet meereist

De opslagmeter splitst hetzelfde uit. Opgeslagen sessies, My images en File results & versions reizen mee in een bundel. De asset-cache, toolpreviews en offline pins daaronder zijn allemaal opnieuw af te leiden, dus blijven achter.

De opslagmeter die de gegevens van dit apparaat onderverdeelt in benoemde categorieën, met Opgeslagen sessies en Mijn afbeeldingen apart bijgehouden van de Assetcache, hier op een verse installatie waar elke categorie nog leeg is signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBControleer het zelfDownload het ondertekende bestandDe opslagmeter die de gegevens van dit apparaat onderverdeelt in benoemde categorieën, met Opgeslagen sessies en Mijn afbeeldingen apart bijgehouden van de Assetcache, hier op een verse installatie waar elke categorie nog leeg is signed by Lollyvector SVG37 paths~4.9k nodes85 groups65 KBControleer het zelfDownload het ondertekende bestand

Garantie over shells heen

data-transfer.ts leest en schrijft uitsluitend via de capability bridge (host.profile, host.state, host.assets) en de gedeelde localStorage-voorkeuren. Dezelfde module leest en schrijft de gemeenschappelijke envelop op web en Tauri, via IndexedDB- of bestandssysteemopslag. Optionele geschiedenisonderdelen verschijnen alleen waar de bijbehorende adapter beschikbaar is; een niet-ondersteund onderdeel wordt bij import als overgeslagen gemeld. De headless suite oefent de gemeenschappelijke onderdelen uit tegen een in-memory bridge, terwijl geschiedenistransacties ook echte browsertests hebben.

Twee shells vallen buiten die garantie, om verschillende redenen:

Gereserveerde uitbreidingspunten

De envelop is door ontwerp een manifest plus een set genoemde onderdelen, zodat nieuwe soorten draagbare gegevens er later zonder een breking wijziging in mee kunnen rijden. Ze passen erin als additieve onderdelen (nieuwe formatVersion, dezelfde minReader), en de lezer van vandaag slaat over wat hij niet herkent. Deze zijn nog niet gebouwd. De namen zijn hier gereserveerd zodat het formaat coherent blijft wanneer ze er komen.

Alles buiten deze gereserveerde namen en de bovenstaande onderdelen is voor een lezer een onbekend onderdeel: ongemoeid gelaten en meegeteld in skipped.

Referentie