[{"data":1,"prerenderedAt":4186},["ShallowReactive",2],{"navigation":3,"\u002Frecipes\u002Frealtime-crdt-app":927},[4,40,114,446,474,498,596,903],{"title":5,"path":6,"stem":7,"children":8},"Architecture","\u002Farchitecture","architecture",[9,14,28,32,36],{"title":10,"path":6,"stem":11,"access":12,"icon":13},"Overview","architecture\u002Findex","public","i-lucide-network",{"title":10,"path":15,"stem":16,"children":17,"access":12,"icon":19},"\u002Farchitecture\u002Fkernel","architecture\u002F1.kernel\u002Findex",[18,20,24],{"title":10,"path":15,"stem":16,"access":12,"icon":19},"i-lucide-box",{"title":21,"path":22,"stem":23,"access":12},"Enclave","\u002Farchitecture\u002Fkernel\u002Fenclave","architecture\u002F1.kernel\u002Fenclave",{"title":25,"path":26,"stem":27,"access":12},"Forking the enclave","\u002Farchitecture\u002Fkernel\u002Fforking-the-enclave","architecture\u002F1.kernel\u002Fforking-the-enclave",{"title":29,"path":30,"stem":31,"access":12},"Ports","\u002Farchitecture\u002Fports","architecture\u002F2.ports",{"title":33,"path":34,"stem":35,"access":12},"Service layers","\u002Farchitecture\u002Fservice-layers","architecture\u002F3.service-layers",{"title":37,"path":38,"stem":39,"access":12},"Families","\u002Farchitecture\u002Ffamilies","architecture\u002F4.families",{"title":41,"path":42,"stem":43,"children":44},"Core","\u002Fcore","core",[45,47,50,53,56,88,97],{"title":10,"path":42,"stem":46,"access":12,"icon":19},"core\u002Findex",{"title":10,"path":48,"stem":49,"access":12},"\u002Fcore\u002F01-overview","core\u002F01-overview",{"title":10,"path":51,"stem":52,"access":12},"\u002Fcore\u002F05-stores","core\u002F05-stores",{"title":10,"path":54,"stem":55,"access":12},"\u002Fcore\u002F06-permissions-and-keyring","core\u002F06-permissions-and-keyring",{"title":10,"path":57,"stem":58,"children":59,"access":12},"\u002Fcore\u002Fnoydb","core\u002F2.noydb\u002Findex",[60,61,65,68,72,76,80,84],{"title":10,"path":57,"stem":58,"access":12},{"title":62,"path":63,"stem":64,"access":12},"Noydb","\u002Fcore\u002Fnoydb\u002Fmethods","core\u002F2.noydb\u002F1.methods",{"title":21,"path":66,"stem":67,"access":12},"\u002Fcore\u002Fnoydb\u002Fenclave","core\u002F2.noydb\u002F2.enclave",{"title":69,"path":70,"stem":71,"access":12},"Secret & keyring","\u002Fcore\u002Fnoydb\u002Fkeyring","core\u002F2.noydb\u002F3.keyring",{"title":73,"path":74,"stem":75,"access":12},"Authentication","\u002Fcore\u002Fnoydb\u002Fauthentication","core\u002F2.noydb\u002F4.authentication",{"title":77,"path":78,"stem":79,"access":12},"Auth recovery","\u002Fcore\u002Fnoydb\u002Frecovery","core\u002F2.noydb\u002F5.recovery",{"title":81,"path":82,"stem":83,"access":12},"Configuration","\u002Fcore\u002Fnoydb\u002Fconfiguration","core\u002F2.noydb\u002F6.configuration",{"title":85,"path":86,"stem":87,"access":12},"Strategies","\u002Fcore\u002Fnoydb\u002Fstrategies","core\u002F2.noydb\u002F7.strategies",{"title":10,"path":89,"stem":90,"children":91,"access":12},"\u002Fcore\u002Fvault","core\u002F3.vault\u002Findex",[92,93],{"title":10,"path":89,"stem":90,"access":12},{"title":94,"path":95,"stem":96,"access":12},"Vault","\u002Fcore\u002Fvault\u002Fmethods","core\u002F3.vault\u002F1.methods",{"title":10,"path":98,"stem":99,"children":100,"access":12},"\u002Fcore\u002Fcollection","core\u002F4.collection\u002Findex",[101,102,106,110],{"title":10,"path":98,"stem":99,"access":12},{"title":103,"path":104,"stem":105,"access":12},"Collection","\u002Fcore\u002Fcollection\u002Fmethods","core\u002F4.collection\u002F1.methods",{"title":107,"path":108,"stem":109,"access":12},"Querying","\u002Fcore\u002Fcollection\u002Fquerying","core\u002F4.collection\u002F2.querying",{"title":111,"path":112,"stem":113,"access":12},"Schema","\u002Fcore\u002Fcollection\u002Fschema","core\u002F4.collection\u002F3.schema",{"title":37,"path":115,"stem":116,"children":117},"\u002Ffamilies","families",[118,121,168,194,208,212,216,294,340],{"title":10,"path":115,"stem":119,"access":12,"icon":120},"families\u002Findex","i-lucide-plug",{"title":122,"path":123,"stem":124,"children":125,"access":12,"icon":127},"as-Exports","\u002Ffamilies\u002Fas","families\u002Fas\u002Findex",[126,128,132,136,140,144,148,152,156,160,164],{"title":122,"path":123,"stem":124,"access":12,"icon":127},"i-lucide-book-open",{"title":129,"path":130,"stem":131,"access":12},"aws-s3","\u002Ffamilies\u002Fas\u002Faws-s3","families\u002Fas\u002Faws-s3",{"title":133,"path":134,"stem":135,"access":12},"blob","\u002Ffamilies\u002Fas\u002Fblob","families\u002Fas\u002Fblob",{"title":137,"path":138,"stem":139,"access":12},"csv","\u002Ffamilies\u002Fas\u002Fcsv","families\u002Fas\u002Fcsv",{"title":141,"path":142,"stem":143,"access":12},"json","\u002Ffamilies\u002Fas\u002Fjson","families\u002Fas\u002Fjson",{"title":145,"path":146,"stem":147,"access":12},"ndjson","\u002Ffamilies\u002Fas\u002Fndjson","families\u002Fas\u002Fndjson",{"title":149,"path":150,"stem":151,"access":12},"noydb","\u002Ffamilies\u002Fas\u002Fnoydb","families\u002Fas\u002Fnoydb",{"title":153,"path":154,"stem":155,"access":12},"sql","\u002Ffamilies\u002Fas\u002Fsql","families\u002Fas\u002Fsql",{"title":157,"path":158,"stem":159,"access":12},"xlsx","\u002Ffamilies\u002Fas\u002Fxlsx","families\u002Fas\u002Fxlsx",{"title":161,"path":162,"stem":163,"access":12},"xml","\u002Ffamilies\u002Fas\u002Fxml","families\u002Fas\u002Fxml",{"title":165,"path":166,"stem":167,"access":12},"zip","\u002Ffamilies\u002Fas\u002Fzip","families\u002Fas\u002Fzip",{"title":169,"path":170,"stem":171,"children":172,"access":12,"icon":127},"at-Seals","\u002Ffamilies\u002Fat","families\u002Fat\u002Findex",[173,174,178,182,186,190],{"title":169,"path":170,"stem":171,"access":12,"icon":127},{"title":175,"path":176,"stem":177,"access":12},"aws-kms","\u002Ffamilies\u002Fat\u002Faws-kms","families\u002Fat\u002Faws-kms",{"title":179,"path":180,"stem":181,"access":12},"azure-keyvault","\u002Ffamilies\u002Fat\u002Fazure-keyvault","families\u002Fat\u002Fazure-keyvault",{"title":183,"path":184,"stem":185,"access":12},"env","\u002Ffamilies\u002Fat\u002Fenv","families\u002Fat\u002Fenv",{"title":187,"path":188,"stem":189,"access":12},"gcp-kms","\u002Ffamilies\u002Fat\u002Fgcp-kms","families\u002Fat\u002Fgcp-kms",{"title":191,"path":192,"stem":193,"access":12},"macos-keychain","\u002Ffamilies\u002Fat\u002Fmacos-keychain","families\u002Fat\u002Fmacos-keychain",{"title":195,"path":196,"stem":197,"children":198,"access":12,"icon":127},"by-Sessions","\u002Ffamilies\u002Fby","families\u002Fby\u002Findex",[199,200,204],{"title":195,"path":196,"stem":197,"access":12,"icon":127},{"title":201,"path":202,"stem":203,"access":12},"peer","\u002Ffamilies\u002Fby\u002Fpeer","families\u002Fby\u002Fpeer",{"title":205,"path":206,"stem":207,"access":12},"tabs","\u002Ffamilies\u002Fby\u002Ftabs","families\u002Fby\u002Ftabs",{"title":209,"path":210,"stem":211,"access":12},"Classifying a package","\u002Ffamilies\u002Fclassification","families\u002Fclassification",{"title":213,"path":214,"stem":215,"access":12},"Command-line tools","\u002Ffamilies\u002Fcli","families\u002Fcli",{"title":217,"path":218,"stem":219,"children":220,"access":12,"icon":127},"in-Frameworks","\u002Ffamilies\u002Fin","families\u002Fin\u002Findex",[221,222,226,230,234,238,242,246,250,254,258,262,266,270,274,278,282,286,290],{"title":217,"path":218,"stem":219,"access":12,"icon":127},{"title":223,"path":224,"stem":225,"access":12},"ai","\u002Ffamilies\u002Fin\u002Fai","families\u002Fin\u002Fai",{"title":227,"path":228,"stem":229,"access":12},"devtools","\u002Ffamilies\u002Fin\u002Fdevtools","families\u002Fin\u002Fdevtools",{"title":231,"path":232,"stem":233,"access":12},"devtools-tui","\u002Ffamilies\u002Fin\u002Fdevtools-tui","families\u002Fin\u002Fdevtools-tui",{"title":235,"path":236,"stem":237,"access":12},"liff","\u002Ffamilies\u002Fin\u002Fliff","families\u002Fin\u002Fliff",{"title":239,"path":240,"stem":241,"access":12},"nextjs","\u002Ffamilies\u002Fin\u002Fnextjs","families\u002Fin\u002Fnextjs",{"title":243,"path":244,"stem":245,"access":12},"nuxt","\u002Ffamilies\u002Fin\u002Fnuxt","families\u002Fin\u002Fnuxt",{"title":247,"path":248,"stem":249,"access":12},"pinia","\u002Ffamilies\u002Fin\u002Fpinia","families\u002Fin\u002Fpinia",{"title":251,"path":252,"stem":253,"access":12},"pwa","\u002Ffamilies\u002Fin\u002Fpwa","families\u002Fin\u002Fpwa",{"title":255,"path":256,"stem":257,"access":12},"react","\u002Ffamilies\u002Fin\u002Freact","families\u002Fin\u002Freact",{"title":259,"path":260,"stem":261,"access":12},"relay","\u002Ffamilies\u002Fin\u002Frelay","families\u002Fin\u002Frelay",{"title":263,"path":264,"stem":265,"access":12},"rest","\u002Ffamilies\u002Fin\u002Frest","families\u002Fin\u002Frest",{"title":267,"path":268,"stem":269,"access":12},"solid","\u002Ffamilies\u002Fin\u002Fsolid","families\u002Fin\u002Fsolid",{"title":271,"path":272,"stem":273,"access":12},"svelte","\u002Ffamilies\u002Fin\u002Fsvelte","families\u002Fin\u002Fsvelte",{"title":275,"path":276,"stem":277,"access":12},"tanstack-query","\u002Ffamilies\u002Fin\u002Ftanstack-query","families\u002Fin\u002Ftanstack-query",{"title":279,"path":280,"stem":281,"access":12},"tanstack-table","\u002Ffamilies\u002Fin\u002Ftanstack-table","families\u002Fin\u002Ftanstack-table",{"title":283,"path":284,"stem":285,"access":12},"vue","\u002Ffamilies\u002Fin\u002Fvue","families\u002Fin\u002Fvue",{"title":287,"path":288,"stem":289,"access":12},"yjs","\u002Ffamilies\u002Fin\u002Fyjs","families\u002Fin\u002Fyjs",{"title":291,"path":292,"stem":293,"access":12},"zustand","\u002Ffamilies\u002Fin\u002Fzustand","families\u002Fin\u002Fzustand",{"title":295,"path":296,"stem":297,"children":298,"access":12,"icon":127},"on-Auth","\u002Ffamilies\u002Fon","families\u002Fon\u002Findex",[299,300,304,308,312,316,320,324,328,332,336],{"title":295,"path":296,"stem":297,"access":12,"icon":127},{"title":301,"path":302,"stem":303,"access":12},"email-otp","\u002Ffamilies\u002Fon\u002Femail-otp","families\u002Fon\u002Femail-otp",{"title":305,"path":306,"stem":307,"access":12},"magic-link","\u002Ffamilies\u002Fon\u002Fmagic-link","families\u002Fon\u002Fmagic-link",{"title":309,"path":310,"stem":311,"access":12},"oidc","\u002Ffamilies\u002Fon\u002Foidc","families\u002Fon\u002Foidc",{"title":313,"path":314,"stem":315,"access":12},"password","\u002Ffamilies\u002Fon\u002Fpassword","families\u002Fon\u002Fpassword",{"title":317,"path":318,"stem":319,"access":12},"pin","\u002Ffamilies\u002Fon\u002Fpin","families\u002Fon\u002Fpin",{"title":321,"path":322,"stem":323,"access":12},"recovery","\u002Ffamilies\u002Fon\u002Frecovery","families\u002Fon\u002Frecovery",{"title":325,"path":326,"stem":327,"access":12},"shamir","\u002Ffamilies\u002Fon\u002Fshamir","families\u002Fon\u002Fshamir",{"title":329,"path":330,"stem":331,"access":12},"threat","\u002Ffamilies\u002Fon\u002Fthreat","families\u002Fon\u002Fthreat",{"title":333,"path":334,"stem":335,"access":12},"totp","\u002Ffamilies\u002Fon\u002Ftotp","families\u002Fon\u002Ftotp",{"title":337,"path":338,"stem":339,"access":12},"webauthn","\u002Ffamilies\u002Fon\u002Fwebauthn","families\u002Fon\u002Fwebauthn",{"title":341,"path":342,"stem":343,"children":344,"access":12,"icon":127},"to-Stores","\u002Ffamilies\u002Fto","families\u002Fto\u002Findex",[345,346,350,353,357,361,365,370,374,378,382,386,390,394,398,402,406,410,414,417,421,425,429,434,438,442],{"title":341,"path":342,"stem":343,"access":12,"icon":127},{"title":347,"path":348,"stem":349,"access":12},"aws-dynamo","\u002Ffamilies\u002Fto\u002Faws-dynamo","families\u002Fto\u002Faws-dynamo",{"title":129,"path":351,"stem":352,"access":12},"\u002Ffamilies\u002Fto\u002Faws-s3","families\u002Fto\u002Faws-s3",{"title":354,"path":355,"stem":356,"access":12},"browser-fs","\u002Ffamilies\u002Fto\u002Fbrowser-fs","families\u002Fto\u002Fbrowser-fs",{"title":358,"path":359,"stem":360,"access":12},"browser-idb","\u002Ffamilies\u002Fto\u002Fbrowser-idb","families\u002Fto\u002Fbrowser-idb",{"title":362,"path":363,"stem":364,"access":12},"browser-local","\u002Ffamilies\u002Fto\u002Fbrowser-local","families\u002Fto\u002Fbrowser-local",{"title":366,"path":367,"stem":368,"access":12,"icon":369},"Choosing a store","\u002Ffamilies\u002Fto\u002Fchoosing-a-store","families\u002Fto\u002Fchoosing-a-store","i-lucide-split",{"title":371,"path":372,"stem":373,"access":12},"cloudflare-d1","\u002Ffamilies\u002Fto\u002Fcloudflare-d1","families\u002Fto\u002Fcloudflare-d1",{"title":375,"path":376,"stem":377,"access":12},"cloudflare-r2","\u002Ffamilies\u002Fto\u002Fcloudflare-r2","families\u002Fto\u002Fcloudflare-r2",{"title":379,"path":380,"stem":381,"access":12},"drive","\u002Ffamilies\u002Fto\u002Fdrive","families\u002Fto\u002Fdrive",{"title":383,"path":384,"stem":385,"access":12},"file","\u002Ffamilies\u002Fto\u002Ffile","families\u002Fto\u002Ffile",{"title":387,"path":388,"stem":389,"access":12},"icloud","\u002Ffamilies\u002Fto\u002Ficloud","families\u002Fto\u002Ficloud",{"title":391,"path":392,"stem":393,"access":12},"memory","\u002Ffamilies\u002Fto\u002Fmemory","families\u002Fto\u002Fmemory",{"title":395,"path":396,"stem":397,"access":12},"meter","\u002Ffamilies\u002Fto\u002Fmeter","families\u002Fto\u002Fmeter",{"title":399,"path":400,"stem":401,"access":12},"mysql","\u002Ffamilies\u002Fto\u002Fmysql","families\u002Fto\u002Fmysql",{"title":403,"path":404,"stem":405,"access":12},"nfs","\u002Ffamilies\u002Fto\u002Fnfs","families\u002Fto\u002Fnfs",{"title":407,"path":408,"stem":409,"access":12},"postgres","\u002Ffamilies\u002Fto\u002Fpostgres","families\u002Fto\u002Fpostgres",{"title":411,"path":412,"stem":413,"access":12},"probe","\u002Ffamilies\u002Fto\u002Fprobe","families\u002Fto\u002Fprobe",{"title":263,"path":415,"stem":416,"access":12},"\u002Ffamilies\u002Fto\u002Frest","families\u002Fto\u002Frest",{"title":418,"path":419,"stem":420,"access":12},"smb","\u002Ffamilies\u002Fto\u002Fsmb","families\u002Fto\u002Fsmb",{"title":422,"path":423,"stem":424,"access":12},"sqlite","\u002Ffamilies\u002Fto\u002Fsqlite","families\u002Fto\u002Fsqlite",{"title":426,"path":427,"stem":428,"access":12},"ssh","\u002Ffamilies\u002Fto\u002Fssh","families\u002Fto\u002Fssh",{"title":430,"path":431,"stem":432,"access":12,"icon":433},"Store-locator descriptors","\u002Ffamilies\u002Fto\u002Fstore-locator","families\u002Fto\u002Fstore-locator","i-lucide-map-pin",{"title":435,"path":436,"stem":437,"access":12},"supabase","\u002Ffamilies\u002Fto\u002Fsupabase","families\u002Fto\u002Fsupabase",{"title":439,"path":440,"stem":441,"access":12},"turso","\u002Ffamilies\u002Fto\u002Fturso","families\u002Fto\u002Fturso",{"title":443,"path":444,"stem":445,"access":12},"webdav","\u002Ffamilies\u002Fto\u002Fwebdav","families\u002Fto\u002Fwebdav",{"title":447,"path":448,"stem":449,"children":450},"Faq","\u002Ffaq","faq",[451,454,458,462,466,470],{"title":10,"path":448,"stem":452,"access":12,"icon":453},"faq\u002Findex","i-lucide-circle-help",{"title":455,"path":456,"stem":457,"access":12},"Where can noy-db run?","\u002Ffaq\u002Fwhere-can-noy-db-run","faq\u002F1.where-can-noy-db-run",{"title":459,"path":460,"stem":461,"access":12},"Native mobile & PWA","\u002Ffaq\u002Fmobile-and-pwa","faq\u002F2.mobile-and-pwa",{"title":463,"path":464,"stem":465,"access":12},"Threat model","\u002Ffaq\u002Fthreat-model","faq\u002F3.threat-model",{"title":467,"path":468,"stem":469,"access":12},"Community & ecosystem","\u002Ffaq\u002Fcommunity-and-ecosystem","faq\u002F4.community-and-ecosystem",{"title":471,"path":472,"stem":473,"access":12},"Licensing","\u002Ffaq\u002Flicensing","faq\u002F5.licensing",{"title":475,"path":476,"stem":477,"children":478},"Glossary","\u002Fglossary","glossary",[479,482,486,490,494],{"title":10,"path":476,"stem":480,"access":12,"icon":481},"glossary\u002Findex","i-lucide-book-a",{"title":483,"path":484,"stem":485,"access":12},"Core vocabulary","\u002Fglossary\u002Fcore-vocabulary","glossary\u002Fcore-vocabulary",{"title":487,"path":488,"stem":489,"access":12},"Deletion vocabulary","\u002Fglossary\u002Fdeletion","glossary\u002Fdeletion",{"title":491,"path":492,"stem":493,"access":12},"Satellite collection vocabulary","\u002Fglossary\u002Fsatellite-collections","glossary\u002Fsatellite-collections",{"title":495,"path":496,"stem":497,"access":12},"Schema migration vocabulary","\u002Fglossary\u002Fschema-migration","glossary\u002Fschema-migration",{"title":499,"path":500,"stem":501,"children":502},"Recipes","\u002Frecipes","recipes",[503,506,510,514,518,522,526,530,534,538,542,546,550,554,558,562,567,571,575,580,584,588,592],{"title":10,"path":500,"stem":504,"access":12,"icon":505},"recipes\u002Findex","i-lucide-play",{"title":507,"path":508,"stem":509,"access":12},"Accounting app","\u002Frecipes\u002Faccounting-app","recipes\u002Faccounting-app",{"title":511,"path":512,"stem":513,"access":12},"Analytics app","\u002Frecipes\u002Fanalytics-app","recipes\u002Fanalytics-app",{"title":515,"path":516,"stem":517,"access":12},"Attestation verifier","\u002Frecipes\u002Fattestation-verifier","recipes\u002Fattestation-verifier",{"title":519,"path":520,"stem":521,"access":12},"AWS-KMS attestation","\u002Frecipes\u002Faws-kms-pdf-attestation","recipes\u002Faws-kms-pdf-attestation",{"title":523,"path":524,"stem":525,"access":12},"Browser durability","\u002Frecipes\u002Fbrowser-durability","recipes\u002Fbrowser-durability",{"title":527,"path":528,"stem":529,"access":12},"Production cloud store","\u002Frecipes\u002Fcloud-store","recipes\u002Fcloud-store",{"title":531,"path":532,"stem":533,"access":12},"Compose your own setup","\u002Frecipes\u002Fcompose-your-own","recipes\u002Fcompose-your-own",{"title":535,"path":536,"stem":537,"access":12},"Confidential HR records","\u002Frecipes\u002Fconfidential-hr","recipes\u002Fconfidential-hr",{"title":539,"path":540,"stem":541,"access":12},"Composing an echo secret","\u002Frecipes\u002Fecho-secret-enrollment","recipes\u002Fecho-secret-enrollment",{"title":543,"path":544,"stem":545,"access":12},"Email archive","\u002Frecipes\u002Femail-archive","recipes\u002Femail-archive",{"title":547,"path":548,"stem":549,"access":12},"Email archive — threads & revisions","\u002Frecipes\u002Femail-archive-threads-revisions","recipes\u002Femail-archive-threads-revisions",{"title":551,"path":552,"stem":553,"access":12},"Export & portability","\u002Frecipes\u002Fexport-portability","recipes\u002Fexport-portability",{"title":555,"path":556,"stem":557,"access":12},"Passwordless OIDC (AWS Cognito)","\u002Frecipes\u002Fpasswordless-oidc","recipes\u002Fpasswordless-oidc",{"title":559,"path":560,"stem":561,"access":12},"Personal notebook","\u002Frecipes\u002Fpersonal-notebook","recipes\u002Fpersonal-notebook",{"title":563,"path":564,"stem":565,"access":12,"icon":566},"Playgrounds","\u002Frecipes\u002Fplaygrounds","recipes\u002Fplaygrounds","i-lucide-gamepad-2",{"title":568,"path":569,"stem":570,"access":12},"React invoice app","\u002Frecipes\u002Freact-invoices","recipes\u002Freact-invoices",{"title":572,"path":573,"stem":574,"access":12},"Collaborative app","\u002Frecipes\u002Frealtime-crdt-app","recipes\u002Frealtime-crdt-app",{"title":576,"path":577,"stem":578,"access":12,"icon":579},"Run the showcases","\u002Frecipes\u002Frun-the-showcases","recipes\u002Frun-the-showcases","i-lucide-flask-conical",{"title":581,"path":582,"stem":583,"access":12},"Search & RAG","\u002Frecipes\u002Fsearch-rag","recipes\u002Fsearch-rag",{"title":585,"path":586,"stem":587,"access":12},"Team vault topology","\u002Frecipes\u002Fteam-vault-topology","recipes\u002Fteam-vault-topology",{"title":589,"path":590,"stem":591,"access":12},"Unlock ceremonies","\u002Frecipes\u002Funlock-ceremonies","recipes\u002Funlock-ceremonies",{"title":593,"path":594,"stem":595,"access":12},"User preferences","\u002Frecipes\u002Fuser-preferences","recipes\u002Fuser-preferences",{"title":597,"path":598,"stem":599,"children":600},"Services","\u002Fservices","services",[601,604,608,612,616,620,624,628,632,636,640,644,648,652,656,660,664,668,672,676,680,684,688,692,696,700,704,710,714,718,722,726,730,734,738,742,746,750,755,759,763,767,771,775,779,783,787,791,795,799,803,807,811,815,819,823,827,831,835,839,843,847,851,855,859,863,867,871,875,879,883,887,891,895,899],{"title":10,"path":598,"stem":602,"access":12,"icon":603},"services\u002Findex","i-lucide-layers",{"title":605,"path":606,"stem":607,"access":12},"archive","\u002Fservices\u002Farchive","services\u002Farchive",{"title":609,"path":610,"stem":611,"access":12},"attestation","\u002Fservices\u002Fattestation","services\u002Fattestation",{"title":613,"path":614,"stem":615,"access":12},"auth-introspection","\u002Fservices\u002Fauth-introspection","services\u002Fauth-introspection",{"title":617,"path":618,"stem":619,"access":12},"auth-landscape","\u002Fservices\u002Fauth-landscape","services\u002Fauth-landscape",{"title":621,"path":622,"stem":623,"access":12},"blobs","\u002Fservices\u002Fblobs","services\u002Fblobs",{"title":625,"path":626,"stem":627,"access":12},"broker","\u002Fservices\u002Fbroker","services\u002Fbroker",{"title":629,"path":630,"stem":631,"access":12},"bundle","\u002Fservices\u002Fbundle","services\u002Fbundle",{"title":633,"path":634,"stem":635,"access":12},"classified","\u002Fservices\u002Fclassified","services\u002Fclassified",{"title":637,"path":638,"stem":639,"access":12},"computed","\u002Fservices\u002Fcomputed","services\u002Fcomputed",{"title":641,"path":642,"stem":643,"access":12},"consent","\u002Fservices\u002Fconsent","services\u002Fconsent",{"title":645,"path":646,"stem":647,"access":12},"cover","\u002Fservices\u002Fcover","services\u002Fcover",{"title":649,"path":650,"stem":651,"access":12},"coverage","\u002Fservices\u002Fcoverage","services\u002Fcoverage",{"title":653,"path":654,"stem":655,"access":12},"crdt","\u002Fservices\u002Fcrdt","services\u002Fcrdt",{"title":657,"path":658,"stem":659,"access":12},"cross-join","\u002Fservices\u002Fcross-join","services\u002Fcross-join",{"title":661,"path":662,"stem":663,"access":12},"custody","\u002Fservices\u002Fcustody","services\u002Fcustody",{"title":665,"path":666,"stem":667,"access":12},"derivations","\u002Fservices\u002Fderivations","services\u002Fderivations",{"title":669,"path":670,"stem":671,"access":12},"directory","\u002Fservices\u002Fdirectory","services\u002Fdirectory",{"title":673,"path":674,"stem":675,"access":12},"search — AI","\u002Fservices\u002Fembeddings","services\u002Fembeddings",{"title":677,"path":678,"stem":679,"access":12},"Field metadata","\u002Fservices\u002Ffield-metadata","services\u002Ffield-metadata",{"title":681,"path":682,"stem":683,"access":12},"Foreign refs","\u002Fservices\u002Fforeign-refs","services\u002Fforeign-refs",{"title":685,"path":686,"stem":687,"access":12},"forget","\u002Fservices\u002Fforget","services\u002Fforget",{"title":689,"path":690,"stem":691,"access":12},"governance","\u002Fservices\u002Fgovernance","services\u002Fgovernance",{"title":693,"path":694,"stem":695,"access":12},"guards","\u002Fservices\u002Fguards","services\u002Fguards",{"title":697,"path":698,"stem":699,"access":12},"history","\u002Fservices\u002Fhistory","services\u002Fhistory",{"title":701,"path":702,"stem":703,"access":12},"i18n","\u002Fservices\u002Fi18n","services\u002Fi18n",{"title":705,"path":706,"stem":707,"children":708,"access":12},"indexing","\u002Fservices\u002Findexing","services\u002Findexing",[709],{"title":705,"path":706,"stem":707,"access":12},{"title":711,"path":712,"stem":713,"access":12},"introspection","\u002Fservices\u002Fintrospection","services\u002Fintrospection",{"title":715,"path":716,"stem":717,"access":12},"joins","\u002Fservices\u002Fjoins","services\u002Fjoins",{"title":719,"path":720,"stem":721,"access":12},"lazy","\u002Fservices\u002Flazy","services\u002Flazy",{"title":723,"path":724,"stem":725,"access":12},"links","\u002Fservices\u002Flinks","services\u002Flinks",{"title":727,"path":728,"stem":729,"access":12},"live","\u002Fservices\u002Flive","services\u002Flive",{"title":731,"path":732,"stem":733,"access":12},"lookup","\u002Fservices\u002Flookup","services\u002Flookup",{"title":735,"path":736,"stem":737,"access":12},"manifest","\u002Fservices\u002Fmanifest","services\u002Fmanifest",{"title":739,"path":740,"stem":741,"access":12},"materialized-views","\u002Fservices\u002Fmaterialized-views","services\u002Fmaterialized-views",{"title":743,"path":744,"stem":745,"access":12},"Metadata ladder","\u002Fservices\u002Fmetadata-ladder","services\u002Fmetadata-ladder",{"title":747,"path":748,"stem":749,"access":12},"Metadata riders","\u002Fservices\u002Fmetadata-riders","services\u002Fmetadata-riders",{"title":751,"path":752,"stem":753,"access":12,"badge":754},"metrics","\u002Fservices\u002Fmetrics","services\u002Fmetrics","Planned",{"title":756,"path":757,"stem":758,"access":12,"badge":754},"migrations","\u002Fservices\u002Fmigrations","services\u002Fmigrations",{"title":760,"path":761,"stem":762,"access":12},"money","\u002Fservices\u002Fmoney","services\u002Fmoney",{"title":764,"path":765,"stem":766,"access":12},"numbering","\u002Fservices\u002Fnumbering","services\u002Fnumbering",{"title":768,"path":769,"stem":770,"access":12},"overlay-views","\u002Fservices\u002Foverlay-views","services\u002Foverlay-views",{"title":772,"path":773,"stem":774,"access":12,"badge":754},"partitioning","\u002Fservices\u002Fpartitioning","services\u002Fpartitioning",{"title":776,"path":777,"stem":778,"access":12},"periods","\u002Fservices\u002Fperiods","services\u002Fperiods",{"title":780,"path":781,"stem":782,"access":12},"persisted-schemas","\u002Fservices\u002Fpersisted-schemas","services\u002Fpersisted-schemas",{"title":784,"path":785,"stem":786,"access":12},"plaintext-bypass","\u002Fservices\u002Fplaintext-bypass","services\u002Fplaintext-bypass",{"title":788,"path":789,"stem":790,"access":12},"pod-redirect","\u002Fservices\u002Fpod-redirect","services\u002Fpod-redirect",{"title":792,"path":793,"stem":794,"access":12},"pod-signature","\u002Fservices\u002Fpod-signature","services\u002Fpod-signature",{"title":796,"path":797,"stem":798,"access":12},"policy","\u002Fservices\u002Fpolicy","services\u002Fpolicy",{"title":800,"path":801,"stem":802,"access":12},"portability","\u002Fservices\u002Fportability","services\u002Fportability",{"title":804,"path":805,"stem":806,"access":12},"reduce","\u002Fservices\u002Freduce","services\u002Freduce",{"title":808,"path":809,"stem":810,"access":12},"routing","\u002Fservices\u002Frouting","services\u002Frouting",{"title":812,"path":813,"stem":814,"access":12},"satellites","\u002Fservices\u002Fsatellites","services\u002Fsatellites",{"title":816,"path":817,"stem":818,"access":12},"schema-identifiers","\u002Fservices\u002Fschema-identifiers","services\u002Fschema-identifiers",{"title":820,"path":821,"stem":822,"access":12},"schema-update","\u002Fservices\u002Fschema-update","services\u002Fschema-update",{"title":824,"path":825,"stem":826,"access":12},"sealed-record","\u002Fservices\u002Fsealed-record","services\u002Fsealed-record",{"title":828,"path":829,"stem":830,"access":12},"sealing provider id","\u002Fservices\u002Fsealing-pid-stability","services\u002Fsealing-pid-stability",{"title":832,"path":833,"stem":834,"access":12},"search — full-text","\u002Fservices\u002Fsearch","services\u002Fsearch",{"title":836,"path":837,"stem":838,"access":12},"sequence","\u002Fservices\u002Fsequence","services\u002Fsequence",{"title":840,"path":841,"stem":842,"access":12},"session","\u002Fservices\u002Fsession","services\u002Fsession",{"title":844,"path":845,"stem":846,"access":12},"session-tiers","\u002Fservices\u002Fsession-tiers","services\u002Fsession-tiers",{"title":848,"path":849,"stem":850,"access":12},"shadow","\u002Fservices\u002Fshadow","services\u002Fshadow",{"title":852,"path":853,"stem":854,"access":12},"share-link","\u002Fservices\u002Fshare-link","services\u002Fshare-link",{"title":856,"path":857,"stem":858,"access":12},"snapshots","\u002Fservices\u002Fsnapshots","services\u002Fsnapshots",{"title":860,"path":861,"stem":862,"access":12},"store capabilities","\u002Fservices\u002Fstorage-capability-matrix","services\u002Fstorage-capability-matrix",{"title":864,"path":865,"stem":866,"access":12},"sync","\u002Fservices\u002Fsync","services\u002Fsync",{"title":868,"path":869,"stem":870,"access":12},"team","\u002Fservices\u002Fteam","services\u002Fteam",{"title":872,"path":873,"stem":874,"access":12},"tiers","\u002Fservices\u002Ftiers","services\u002Ftiers",{"title":876,"path":877,"stem":878,"access":12},"transactions","\u002Fservices\u002Ftransactions","services\u002Ftransactions",{"title":880,"path":881,"stem":882,"access":12},"partitions","\u002Fservices\u002Ftransferable-partitions","services\u002Ftransferable-partitions",{"title":884,"path":885,"stem":886,"access":12},"user-envelope","\u002Fservices\u002Fuser-envelope","services\u002Fuser-envelope",{"title":888,"path":889,"stem":890,"access":12,"badge":754},"validation","\u002Fservices\u002Fvalidation","services\u002Fvalidation",{"title":892,"path":893,"stem":894,"access":12},"vault-head","\u002Fservices\u002Fvault-head","services\u002Fvault-head",{"title":896,"path":897,"stem":898,"access":12},"via","\u002Fservices\u002Fvia","services\u002Fvia",{"title":900,"path":901,"stem":902,"access":12},"withdrawal","\u002Fservices\u002Fwithdrawal","services\u002Fwithdrawal",{"title":904,"path":905,"stem":906,"children":907},"Start","\u002Fstart","start",[908,911,915,919,923],{"title":10,"path":905,"stem":909,"access":12,"icon":910},"start\u002Findex","i-lucide-flag",{"title":912,"path":913,"stem":914,"access":12},"Install","\u002Fstart\u002Finstall","start\u002F1.install",{"title":916,"path":917,"stem":918,"access":12},"Your first vault","\u002Fstart\u002Ffirst-vault","start\u002F2.first-vault",{"title":920,"path":921,"stem":922,"access":12},"Your first service","\u002Fstart\u002Ffirst-service","start\u002F3.first-service",{"title":924,"path":925,"stem":926,"access":12},"See the ciphertext","\u002Fstart\u002Fsee-the-ciphertext","start\u002F4.see-the-ciphertext",{"id":928,"title":572,"access":12,"apiToc":929,"body":930,"category":4178,"description":4179,"extension":4180,"meta":4181,"navigation":4178,"nest":4178,"path":573,"seo":4182,"sinceVersion":4178,"status":4183,"stem":574,"subtitle":4178,"tier":4184,"tocExternal":4178,"__hash__":4185},"docs\u002Frecipes\u002Frealtime-crdt-app.md",false,{"type":931,"value":932,"toc":4166},"minimark",[933,937,971,1004,1020,1025,1140,1156,1160,1166,1757,1764,1768,1790,2191,2209,2220,2224,2227,2705,2716,2720,2731,2912,3023,3034,3038,3046,3332,3339,3349,3367,3371,3378,3563,3593,3596,3717,3728,3732,3744,3760,3818,3830,3943,4009,4015,4044,4048,4102,4106,4162],[934,935,572],"h1",{"id":936},"collaborative-app",[938,939,940],"blockquote",{},[941,942,943,947,948,951,952,956,957,956,960,956,963,966,967,970],"p",{},[944,945,946],"strong",{},"Audience:"," collaborative editors, live cursors, shared whiteboards, multi-device personal apps — two or more people editing the same documents at once, with every device converging on the same merged result and the server never seeing a word of the content.\n",[944,949,950],{},"Bundle:"," core + ",[953,954,955],"code",{},"withCrdt()"," + ",[953,958,959],{},"withSync()",[953,961,962],{},"withTeam()",[953,964,965],{},"withSession()",". Live query updates (",[953,968,969],{},"collection.query().live()",") are part of the core — no opt-in needed.",[941,972,973,976,977,980,981,984,985,988,989,992,993,995,996,999,1000,1003],{},[944,974,975],{},"Verified by:"," the runnable test ",[953,978,979],{},"showcases\u002Fsrc\u002Frecipe-realtime-crdt.recipe.test.ts"," in the documentation repository covers the Yjs ",[953,982,983],{},"getYDoc","\u002F",[953,986,987],{},"putYDoc"," round-trip, concurrent-edit CRDT convergence via ",[953,990,991],{},"Y.applyUpdate",", and the error thrown when ",[953,994,955],{}," is omitted. Push\u002Fpull replication and team grants (the sections below) are covered separately by ",[953,997,998],{},"showcases\u002Fsrc\u002F15-with-sync.showcase.test.ts"," and ",[953,1001,1002],{},"showcases\u002Fsrc\u002F06-multi-user.showcase.test.ts",". Presence, conflict-resolution strategies, and session-policy enforcement are not exercised by an automated test in this repository.",[941,1005,1006,1007,984,1010,1013,1014,1019],{},"noy-db is an encrypted document store: records are encrypted inside your app's process before they reach any storage backend, so the backend only ever holds ciphertext. This recipe adds the collaborative layer on top: CRDTs (conflict-free replicated data types — data structures where concurrent edits merge deterministically instead of overwriting each other), replication between devices via ",[953,1008,1009],{},"push()",[953,1011,1012],{},"pull()",", live presence (\"who else is looking at this?\"), and multi-user access grants. If this is your first noy-db app, read ",[1015,1016,1018],"a",{"href":1017},".\u002Fpersonal-notebook","Recipe 1 — Personal encrypted notebook"," first; this recipe builds on the same core.",[1021,1022,1024],"h2",{"id":1023},"what-this-gets-you","What this gets you",[1026,1027,1028,1041],"table",{},[1029,1030,1031],"thead",{},[1032,1033,1034,1038],"tr",{},[1035,1036,1037],"th",{},"Service",[1035,1039,1040],{},"What it adds",[1042,1043,1044,1069,1091,1112,1127],"tbody",{},[1032,1045,1046,1055],{},[1047,1048,1049,1051,1052],"td",{},[953,1050,955],{}," from ",[953,1053,1054],{},"@noy-db\u002Fhub\u002Fcrdt",[1047,1056,1057,1058,1061,1062,1065,1066],{},"Conflict-free merge for collections declared with ",[953,1059,1060],{},"crdt: 'lww-map'",", ",[953,1063,1064],{},"'rga'",", or ",[953,1067,1068],{},"'yjs'",[1032,1070,1071,1078],{},[1047,1072,1073,1051,1075],{},[953,1074,959],{},[953,1076,1077],{},"@noy-db\u002Fhub\u002Fsync",[1047,1079,1080,1083,1084,1087,1088],{},[953,1081,1082],{},"db.push()"," \u002F ",[953,1085,1086],{},"db.pull()"," replication against a remote store, plus ",[953,1089,1090],{},"collection.presence()",[1032,1092,1093,1100],{},[1047,1094,1095,1051,1097],{},[953,1096,962],{},[953,1098,1099],{},"@noy-db\u002Fhub\u002Fteam",[1047,1101,1102,1103,1083,1106,1083,1109],{},"Multi-user access: ",[953,1104,1105],{},"db.grant()",[953,1107,1108],{},"db.revoke()",[953,1110,1111],{},"db.listUsers()",[1032,1113,1114,1121],{},[1047,1115,1116,1051,1118],{},[953,1117,965],{},[953,1119,1120],{},"@noy-db\u002Fhub\u002Fsession",[1047,1122,1123,1126],{},[953,1124,1125],{},"sessionPolicy"," enforcement: idle and absolute timeouts, lock-on-background",[1032,1128,1129,1137],{},[1047,1130,1131,1051,1134],{},[953,1132,1133],{},"withHistory()",[953,1135,1136],{},"@noy-db\u002Fhub\u002Fhistory",[1047,1138,1139],{},"(Optional) an audit trail of every change — not used below",[941,1141,1142,1143,1145,1146,1061,1149,1061,1152,1155],{},"Reactive UI updates need no service at all: ",[953,1144,969],{}," returns a live query that re-runs on every mutation, and the framework bindings (",[953,1147,1148],{},"@noy-db\u002Fin-react",[953,1150,1151],{},"@noy-db\u002Fin-vue",[953,1153,1154],{},"@noy-db\u002Fin-pinia",", …) build on it.",[1021,1157,1159],{"id":1158},"setup","Setup",[941,1161,1162,1163,1165],{},"Run this same setup on every device. The local store keeps the app offline-first; the ",[953,1164,864],{}," target is the remote the devices replicate through — it only ever receives ciphertext.",[1167,1168,1173],"pre",{"className":1169,"code":1170,"language":1171,"meta":1172,"style":1172},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createNoydb } from '@noy-db\u002Fhub'\nimport { withCrdt } from '@noy-db\u002Fhub\u002Fcrdt'\nimport { withSync } from '@noy-db\u002Fhub\u002Fsync'\nimport { withTeam } from '@noy-db\u002Fhub\u002Fteam'\nimport { withSession } from '@noy-db\u002Fhub\u002Fsession'\nimport { toBrowserIdb } from '@noy-db\u002Fto-browser-idb'\nimport { toCloudflareR2 } from '@noy-db\u002Fto-cloudflare-r2'\n\n\u002F\u002F The shared remote — any store adapter works (S3, Postgres, a synced\n\u002F\u002F file directory, …). Cloudflare R2 shown here.\n\u002F\u002F Never put R2 keys in browser code. The callback fetches short-lived\n\u002F\u002F `kind: 'aws'` credentials from your own server, which holds the real keys;\n\u002F\u002F the store re-invokes it near `expiresAt`.\nconst remote = toCloudflareR2({\n  accountId: 'your-cloudflare-account-id',\n  bucket: 'collab-app',\n  credentials: async () => (await fetch('\u002Fapi\u002Fr2-credentials')).json(),\n})\n\nconst db = await createNoydb({\n  store: toBrowserIdb(),                \u002F\u002F local, offline-first cache\n  sync: { store: remote, role: 'sync-peer' }, \u002F\u002F bidirectional push\u002Fpull\n  user: 'alice',\n  secret: 'correct-horse-battery-staple',  \u002F\u002F secret — derives the encryption keys\n\n  crdtStrategy: withCrdt(),\n  syncStrategy: withSync(),\n  teamStrategy: withTeam(),\n  sessionStrategy: withSession(),\n\n  sessionPolicy: {\n    idleTimeoutMs: 15 * 60_000,        \u002F\u002F lock after 15 min idle\n    absoluteTimeoutMs: 8 * 60 * 60_000, \u002F\u002F …and after 8 h regardless\n    lockOnBackground: true,             \u002F\u002F lock when the tab is backgrounded\n  },\n})\n","ts","",[953,1174,1175,1208,1228,1248,1268,1288,1309,1330,1337,1344,1350,1356,1362,1368,1390,1411,1428,1476,1485,1490,1509,1527,1565,1582,1602,1607,1621,1635,1649,1663,1668,1679,1702,1727,1744,1750],{"__ignoreMap":1172},[1176,1177,1180,1184,1188,1192,1195,1198,1201,1205],"span",{"class":1178,"line":1179},"line",1,[1176,1181,1183],{"class":1182},"s7zQu","import",[1176,1185,1187],{"class":1186},"sMK4o"," {",[1176,1189,1191],{"class":1190},"sTEyZ"," createNoydb",[1176,1193,1194],{"class":1186}," }",[1176,1196,1197],{"class":1182}," from",[1176,1199,1200],{"class":1186}," '",[1176,1202,1204],{"class":1203},"sfazB","@noy-db\u002Fhub",[1176,1206,1207],{"class":1186},"'\n",[1176,1209,1211,1213,1215,1218,1220,1222,1224,1226],{"class":1178,"line":1210},2,[1176,1212,1183],{"class":1182},[1176,1214,1187],{"class":1186},[1176,1216,1217],{"class":1190}," withCrdt",[1176,1219,1194],{"class":1186},[1176,1221,1197],{"class":1182},[1176,1223,1200],{"class":1186},[1176,1225,1054],{"class":1203},[1176,1227,1207],{"class":1186},[1176,1229,1231,1233,1235,1238,1240,1242,1244,1246],{"class":1178,"line":1230},3,[1176,1232,1183],{"class":1182},[1176,1234,1187],{"class":1186},[1176,1236,1237],{"class":1190}," withSync",[1176,1239,1194],{"class":1186},[1176,1241,1197],{"class":1182},[1176,1243,1200],{"class":1186},[1176,1245,1077],{"class":1203},[1176,1247,1207],{"class":1186},[1176,1249,1251,1253,1255,1258,1260,1262,1264,1266],{"class":1178,"line":1250},4,[1176,1252,1183],{"class":1182},[1176,1254,1187],{"class":1186},[1176,1256,1257],{"class":1190}," withTeam",[1176,1259,1194],{"class":1186},[1176,1261,1197],{"class":1182},[1176,1263,1200],{"class":1186},[1176,1265,1099],{"class":1203},[1176,1267,1207],{"class":1186},[1176,1269,1271,1273,1275,1278,1280,1282,1284,1286],{"class":1178,"line":1270},5,[1176,1272,1183],{"class":1182},[1176,1274,1187],{"class":1186},[1176,1276,1277],{"class":1190}," withSession",[1176,1279,1194],{"class":1186},[1176,1281,1197],{"class":1182},[1176,1283,1200],{"class":1186},[1176,1285,1120],{"class":1203},[1176,1287,1207],{"class":1186},[1176,1289,1291,1293,1295,1298,1300,1302,1304,1307],{"class":1178,"line":1290},6,[1176,1292,1183],{"class":1182},[1176,1294,1187],{"class":1186},[1176,1296,1297],{"class":1190}," toBrowserIdb",[1176,1299,1194],{"class":1186},[1176,1301,1197],{"class":1182},[1176,1303,1200],{"class":1186},[1176,1305,1306],{"class":1203},"@noy-db\u002Fto-browser-idb",[1176,1308,1207],{"class":1186},[1176,1310,1312,1314,1316,1319,1321,1323,1325,1328],{"class":1178,"line":1311},7,[1176,1313,1183],{"class":1182},[1176,1315,1187],{"class":1186},[1176,1317,1318],{"class":1190}," toCloudflareR2",[1176,1320,1194],{"class":1186},[1176,1322,1197],{"class":1182},[1176,1324,1200],{"class":1186},[1176,1326,1327],{"class":1203},"@noy-db\u002Fto-cloudflare-r2",[1176,1329,1207],{"class":1186},[1176,1331,1333],{"class":1178,"line":1332},8,[1176,1334,1336],{"emptyLinePlaceholder":1335},true,"\n",[1176,1338,1340],{"class":1178,"line":1339},9,[1176,1341,1343],{"class":1342},"sHwdD","\u002F\u002F The shared remote — any store adapter works (S3, Postgres, a synced\n",[1176,1345,1347],{"class":1178,"line":1346},10,[1176,1348,1349],{"class":1342},"\u002F\u002F file directory, …). Cloudflare R2 shown here.\n",[1176,1351,1353],{"class":1178,"line":1352},11,[1176,1354,1355],{"class":1342},"\u002F\u002F Never put R2 keys in browser code. The callback fetches short-lived\n",[1176,1357,1359],{"class":1178,"line":1358},12,[1176,1360,1361],{"class":1342},"\u002F\u002F `kind: 'aws'` credentials from your own server, which holds the real keys;\n",[1176,1363,1365],{"class":1178,"line":1364},13,[1176,1366,1367],{"class":1342},"\u002F\u002F the store re-invokes it near `expiresAt`.\n",[1176,1369,1371,1375,1378,1381,1384,1387],{"class":1178,"line":1370},14,[1176,1372,1374],{"class":1373},"spNyl","const",[1176,1376,1377],{"class":1190}," remote ",[1176,1379,1380],{"class":1186},"=",[1176,1382,1318],{"class":1383},"s2Zo4",[1176,1385,1386],{"class":1190},"(",[1176,1388,1389],{"class":1186},"{\n",[1176,1391,1393,1397,1400,1402,1405,1408],{"class":1178,"line":1392},15,[1176,1394,1396],{"class":1395},"swJcz","  accountId",[1176,1398,1399],{"class":1186},":",[1176,1401,1200],{"class":1186},[1176,1403,1404],{"class":1203},"your-cloudflare-account-id",[1176,1406,1407],{"class":1186},"'",[1176,1409,1410],{"class":1186},",\n",[1176,1412,1414,1417,1419,1421,1424,1426],{"class":1178,"line":1413},16,[1176,1415,1416],{"class":1395},"  bucket",[1176,1418,1399],{"class":1186},[1176,1420,1200],{"class":1186},[1176,1422,1423],{"class":1203},"collab-app",[1176,1425,1407],{"class":1186},[1176,1427,1410],{"class":1186},[1176,1429,1431,1434,1436,1439,1442,1445,1448,1451,1454,1456,1458,1461,1463,1466,1469,1471,1474],{"class":1178,"line":1430},17,[1176,1432,1433],{"class":1383},"  credentials",[1176,1435,1399],{"class":1186},[1176,1437,1438],{"class":1373}," async",[1176,1440,1441],{"class":1186}," ()",[1176,1443,1444],{"class":1373}," =>",[1176,1446,1447],{"class":1190}," (",[1176,1449,1450],{"class":1182},"await",[1176,1452,1453],{"class":1383}," fetch",[1176,1455,1386],{"class":1190},[1176,1457,1407],{"class":1186},[1176,1459,1460],{"class":1203},"\u002Fapi\u002Fr2-credentials",[1176,1462,1407],{"class":1186},[1176,1464,1465],{"class":1190},"))",[1176,1467,1468],{"class":1186},".",[1176,1470,141],{"class":1383},[1176,1472,1473],{"class":1190},"()",[1176,1475,1410],{"class":1186},[1176,1477,1479,1482],{"class":1178,"line":1478},18,[1176,1480,1481],{"class":1186},"}",[1176,1483,1484],{"class":1190},")\n",[1176,1486,1488],{"class":1178,"line":1487},19,[1176,1489,1336],{"emptyLinePlaceholder":1335},[1176,1491,1493,1495,1498,1500,1503,1505,1507],{"class":1178,"line":1492},20,[1176,1494,1374],{"class":1373},[1176,1496,1497],{"class":1190}," db ",[1176,1499,1380],{"class":1186},[1176,1501,1502],{"class":1182}," await",[1176,1504,1191],{"class":1383},[1176,1506,1386],{"class":1190},[1176,1508,1389],{"class":1186},[1176,1510,1512,1515,1517,1519,1521,1524],{"class":1178,"line":1511},21,[1176,1513,1514],{"class":1395},"  store",[1176,1516,1399],{"class":1186},[1176,1518,1297],{"class":1383},[1176,1520,1473],{"class":1190},[1176,1522,1523],{"class":1186},",",[1176,1525,1526],{"class":1342},"                \u002F\u002F local, offline-first cache\n",[1176,1528,1530,1533,1535,1537,1540,1542,1545,1547,1550,1552,1554,1557,1559,1562],{"class":1178,"line":1529},22,[1176,1531,1532],{"class":1395},"  sync",[1176,1534,1399],{"class":1186},[1176,1536,1187],{"class":1186},[1176,1538,1539],{"class":1395}," store",[1176,1541,1399],{"class":1186},[1176,1543,1544],{"class":1190}," remote",[1176,1546,1523],{"class":1186},[1176,1548,1549],{"class":1395}," role",[1176,1551,1399],{"class":1186},[1176,1553,1200],{"class":1186},[1176,1555,1556],{"class":1203},"sync-peer",[1176,1558,1407],{"class":1186},[1176,1560,1561],{"class":1186}," },",[1176,1563,1564],{"class":1342}," \u002F\u002F bidirectional push\u002Fpull\n",[1176,1566,1568,1571,1573,1575,1578,1580],{"class":1178,"line":1567},23,[1176,1569,1570],{"class":1395},"  user",[1176,1572,1399],{"class":1186},[1176,1574,1200],{"class":1186},[1176,1576,1577],{"class":1203},"alice",[1176,1579,1407],{"class":1186},[1176,1581,1410],{"class":1186},[1176,1583,1585,1588,1590,1592,1595,1597,1599],{"class":1178,"line":1584},24,[1176,1586,1587],{"class":1395},"  secret",[1176,1589,1399],{"class":1186},[1176,1591,1200],{"class":1186},[1176,1593,1594],{"class":1203},"correct-horse-battery-staple",[1176,1596,1407],{"class":1186},[1176,1598,1523],{"class":1186},[1176,1600,1601],{"class":1342},"  \u002F\u002F secret — derives the encryption keys\n",[1176,1603,1605],{"class":1178,"line":1604},25,[1176,1606,1336],{"emptyLinePlaceholder":1335},[1176,1608,1610,1613,1615,1617,1619],{"class":1178,"line":1609},26,[1176,1611,1612],{"class":1395},"  crdtStrategy",[1176,1614,1399],{"class":1186},[1176,1616,1217],{"class":1383},[1176,1618,1473],{"class":1190},[1176,1620,1410],{"class":1186},[1176,1622,1624,1627,1629,1631,1633],{"class":1178,"line":1623},27,[1176,1625,1626],{"class":1395},"  syncStrategy",[1176,1628,1399],{"class":1186},[1176,1630,1237],{"class":1383},[1176,1632,1473],{"class":1190},[1176,1634,1410],{"class":1186},[1176,1636,1638,1641,1643,1645,1647],{"class":1178,"line":1637},28,[1176,1639,1640],{"class":1395},"  teamStrategy",[1176,1642,1399],{"class":1186},[1176,1644,1257],{"class":1383},[1176,1646,1473],{"class":1190},[1176,1648,1410],{"class":1186},[1176,1650,1652,1655,1657,1659,1661],{"class":1178,"line":1651},29,[1176,1653,1654],{"class":1395},"  sessionStrategy",[1176,1656,1399],{"class":1186},[1176,1658,1277],{"class":1383},[1176,1660,1473],{"class":1190},[1176,1662,1410],{"class":1186},[1176,1664,1666],{"class":1178,"line":1665},30,[1176,1667,1336],{"emptyLinePlaceholder":1335},[1176,1669,1671,1674,1676],{"class":1178,"line":1670},31,[1176,1672,1673],{"class":1395},"  sessionPolicy",[1176,1675,1399],{"class":1186},[1176,1677,1678],{"class":1186}," {\n",[1176,1680,1682,1685,1687,1691,1694,1697,1699],{"class":1178,"line":1681},32,[1176,1683,1684],{"class":1395},"    idleTimeoutMs",[1176,1686,1399],{"class":1186},[1176,1688,1690],{"class":1689},"sbssI"," 15",[1176,1692,1693],{"class":1186}," *",[1176,1695,1696],{"class":1689}," 60_000",[1176,1698,1523],{"class":1186},[1176,1700,1701],{"class":1342},"        \u002F\u002F lock after 15 min idle\n",[1176,1703,1705,1708,1710,1713,1715,1718,1720,1722,1724],{"class":1178,"line":1704},33,[1176,1706,1707],{"class":1395},"    absoluteTimeoutMs",[1176,1709,1399],{"class":1186},[1176,1711,1712],{"class":1689}," 8",[1176,1714,1693],{"class":1186},[1176,1716,1717],{"class":1689}," 60",[1176,1719,1693],{"class":1186},[1176,1721,1696],{"class":1689},[1176,1723,1523],{"class":1186},[1176,1725,1726],{"class":1342}," \u002F\u002F …and after 8 h regardless\n",[1176,1728,1730,1733,1735,1739,1741],{"class":1178,"line":1729},34,[1176,1731,1732],{"class":1395},"    lockOnBackground",[1176,1734,1399],{"class":1186},[1176,1736,1738],{"class":1737},"sfNiH"," true",[1176,1740,1523],{"class":1186},[1176,1742,1743],{"class":1342},"             \u002F\u002F lock when the tab is backgrounded\n",[1176,1745,1747],{"class":1178,"line":1746},35,[1176,1748,1749],{"class":1186},"  },\n",[1176,1751,1753,1755],{"class":1178,"line":1752},36,[1176,1754,1481],{"class":1186},[1176,1756,1484],{"class":1190},[941,1758,1759,1760,1763],{},"Each service is a tree-shakeable opt-in: if you skip a ",[953,1761,1762],{},"*Strategy"," entry, its code stays out of your bundle, and calling its surface throws an error that names the subpath to import.",[1021,1765,1767],{"id":1766},"define-a-crdt-backed-collection","Define a CRDT-backed collection",[941,1769,1770,1771,1777,1778,1781,1782,1785,1786,1789],{},"For rich-text collaboration, use the ",[1015,1772,1776],{"href":1773,"rel":1774},"https:\u002F\u002Fyjs.dev",[1775],"nofollow","Yjs"," binding from ",[953,1779,1780],{},"@noy-db\u002Fin-yjs",". ",[953,1783,1784],{},"yjsCollection()"," wraps a ",[953,1787,1788],{},"crdt: 'yjs'"," collection and stores each document as an encrypted Yjs update — the storage backend sees neither the text nor its structure.",[1167,1791,1793],{"className":1169,"code":1792,"language":1171,"meta":1172,"style":1172},"import { yjsCollection, yText, yMap } from '@noy-db\u002Fin-yjs'\n\nconst vault = await db.openVault('shared')\n\nconst docs = yjsCollection(vault, 'docs', {\n  yFields: { body: yText(), meta: yMap() },\n})\n\nconst doc = await docs.getYDoc('doc-1')   \u002F\u002F fresh empty Y.Doc if the record is new\ndoc.getText('body').insert(0, 'Hello, world')\ndoc.getMap('meta').set('author', 'alice')\nawait docs.putYDoc('doc-1', doc)\n\nconst reloaded = await docs.getYDoc('doc-1')\nconsole.log(reloaded.getText('body').toString())\n\u002F\u002F → \"Hello, world\"\nconsole.log(reloaded.getMap('meta').get('author'))\n\u002F\u002F → \"alice\"\n",[953,1794,1795,1824,1828,1858,1862,1889,1922,1928,1932,1965,2008,2052,2075,2079,2106,2141,2146,2186],{"__ignoreMap":1172},[1176,1796,1797,1799,1801,1804,1806,1809,1811,1814,1816,1818,1820,1822],{"class":1178,"line":1179},[1176,1798,1183],{"class":1182},[1176,1800,1187],{"class":1186},[1176,1802,1803],{"class":1190}," yjsCollection",[1176,1805,1523],{"class":1186},[1176,1807,1808],{"class":1190}," yText",[1176,1810,1523],{"class":1186},[1176,1812,1813],{"class":1190}," yMap",[1176,1815,1194],{"class":1186},[1176,1817,1197],{"class":1182},[1176,1819,1200],{"class":1186},[1176,1821,1780],{"class":1203},[1176,1823,1207],{"class":1186},[1176,1825,1826],{"class":1178,"line":1210},[1176,1827,1336],{"emptyLinePlaceholder":1335},[1176,1829,1830,1832,1835,1837,1839,1842,1844,1847,1849,1851,1854,1856],{"class":1178,"line":1230},[1176,1831,1374],{"class":1373},[1176,1833,1834],{"class":1190}," vault ",[1176,1836,1380],{"class":1186},[1176,1838,1502],{"class":1182},[1176,1840,1841],{"class":1190}," db",[1176,1843,1468],{"class":1186},[1176,1845,1846],{"class":1383},"openVault",[1176,1848,1386],{"class":1190},[1176,1850,1407],{"class":1186},[1176,1852,1853],{"class":1203},"shared",[1176,1855,1407],{"class":1186},[1176,1857,1484],{"class":1190},[1176,1859,1860],{"class":1178,"line":1250},[1176,1861,1336],{"emptyLinePlaceholder":1335},[1176,1863,1864,1866,1869,1871,1873,1876,1878,1880,1883,1885,1887],{"class":1178,"line":1270},[1176,1865,1374],{"class":1373},[1176,1867,1868],{"class":1190}," docs ",[1176,1870,1380],{"class":1186},[1176,1872,1803],{"class":1383},[1176,1874,1875],{"class":1190},"(vault",[1176,1877,1523],{"class":1186},[1176,1879,1200],{"class":1186},[1176,1881,1882],{"class":1203},"docs",[1176,1884,1407],{"class":1186},[1176,1886,1523],{"class":1186},[1176,1888,1678],{"class":1186},[1176,1890,1891,1894,1896,1898,1901,1903,1905,1907,1909,1912,1914,1916,1919],{"class":1178,"line":1290},[1176,1892,1893],{"class":1395},"  yFields",[1176,1895,1399],{"class":1186},[1176,1897,1187],{"class":1186},[1176,1899,1900],{"class":1395}," body",[1176,1902,1399],{"class":1186},[1176,1904,1808],{"class":1383},[1176,1906,1473],{"class":1190},[1176,1908,1523],{"class":1186},[1176,1910,1911],{"class":1395}," meta",[1176,1913,1399],{"class":1186},[1176,1915,1813],{"class":1383},[1176,1917,1918],{"class":1190},"() ",[1176,1920,1921],{"class":1186},"},\n",[1176,1923,1924,1926],{"class":1178,"line":1311},[1176,1925,1481],{"class":1186},[1176,1927,1484],{"class":1190},[1176,1929,1930],{"class":1178,"line":1332},[1176,1931,1336],{"emptyLinePlaceholder":1335},[1176,1933,1934,1936,1939,1941,1943,1946,1948,1950,1952,1954,1957,1959,1962],{"class":1178,"line":1339},[1176,1935,1374],{"class":1373},[1176,1937,1938],{"class":1190}," doc ",[1176,1940,1380],{"class":1186},[1176,1942,1502],{"class":1182},[1176,1944,1945],{"class":1190}," docs",[1176,1947,1468],{"class":1186},[1176,1949,983],{"class":1383},[1176,1951,1386],{"class":1190},[1176,1953,1407],{"class":1186},[1176,1955,1956],{"class":1203},"doc-1",[1176,1958,1407],{"class":1186},[1176,1960,1961],{"class":1190},")   ",[1176,1963,1964],{"class":1342},"\u002F\u002F fresh empty Y.Doc if the record is new\n",[1176,1966,1967,1970,1972,1975,1977,1979,1982,1984,1987,1989,1992,1994,1997,1999,2001,2004,2006],{"class":1178,"line":1346},[1176,1968,1969],{"class":1190},"doc",[1176,1971,1468],{"class":1186},[1176,1973,1974],{"class":1383},"getText",[1176,1976,1386],{"class":1190},[1176,1978,1407],{"class":1186},[1176,1980,1981],{"class":1203},"body",[1176,1983,1407],{"class":1186},[1176,1985,1986],{"class":1190},")",[1176,1988,1468],{"class":1186},[1176,1990,1991],{"class":1383},"insert",[1176,1993,1386],{"class":1190},[1176,1995,1996],{"class":1689},"0",[1176,1998,1523],{"class":1186},[1176,2000,1200],{"class":1186},[1176,2002,2003],{"class":1203},"Hello, world",[1176,2005,1407],{"class":1186},[1176,2007,1484],{"class":1190},[1176,2009,2010,2012,2014,2017,2019,2021,2024,2026,2028,2030,2033,2035,2037,2040,2042,2044,2046,2048,2050],{"class":1178,"line":1352},[1176,2011,1969],{"class":1190},[1176,2013,1468],{"class":1186},[1176,2015,2016],{"class":1383},"getMap",[1176,2018,1386],{"class":1190},[1176,2020,1407],{"class":1186},[1176,2022,2023],{"class":1203},"meta",[1176,2025,1407],{"class":1186},[1176,2027,1986],{"class":1190},[1176,2029,1468],{"class":1186},[1176,2031,2032],{"class":1383},"set",[1176,2034,1386],{"class":1190},[1176,2036,1407],{"class":1186},[1176,2038,2039],{"class":1203},"author",[1176,2041,1407],{"class":1186},[1176,2043,1523],{"class":1186},[1176,2045,1200],{"class":1186},[1176,2047,1577],{"class":1203},[1176,2049,1407],{"class":1186},[1176,2051,1484],{"class":1190},[1176,2053,2054,2056,2058,2060,2062,2064,2066,2068,2070,2072],{"class":1178,"line":1358},[1176,2055,1450],{"class":1182},[1176,2057,1945],{"class":1190},[1176,2059,1468],{"class":1186},[1176,2061,987],{"class":1383},[1176,2063,1386],{"class":1190},[1176,2065,1407],{"class":1186},[1176,2067,1956],{"class":1203},[1176,2069,1407],{"class":1186},[1176,2071,1523],{"class":1186},[1176,2073,2074],{"class":1190}," doc)\n",[1176,2076,2077],{"class":1178,"line":1364},[1176,2078,1336],{"emptyLinePlaceholder":1335},[1176,2080,2081,2083,2086,2088,2090,2092,2094,2096,2098,2100,2102,2104],{"class":1178,"line":1370},[1176,2082,1374],{"class":1373},[1176,2084,2085],{"class":1190}," reloaded ",[1176,2087,1380],{"class":1186},[1176,2089,1502],{"class":1182},[1176,2091,1945],{"class":1190},[1176,2093,1468],{"class":1186},[1176,2095,983],{"class":1383},[1176,2097,1386],{"class":1190},[1176,2099,1407],{"class":1186},[1176,2101,1956],{"class":1203},[1176,2103,1407],{"class":1186},[1176,2105,1484],{"class":1190},[1176,2107,2108,2111,2113,2116,2119,2121,2123,2125,2127,2129,2131,2133,2135,2138],{"class":1178,"line":1392},[1176,2109,2110],{"class":1190},"console",[1176,2112,1468],{"class":1186},[1176,2114,2115],{"class":1383},"log",[1176,2117,2118],{"class":1190},"(reloaded",[1176,2120,1468],{"class":1186},[1176,2122,1974],{"class":1383},[1176,2124,1386],{"class":1190},[1176,2126,1407],{"class":1186},[1176,2128,1981],{"class":1203},[1176,2130,1407],{"class":1186},[1176,2132,1986],{"class":1190},[1176,2134,1468],{"class":1186},[1176,2136,2137],{"class":1383},"toString",[1176,2139,2140],{"class":1190},"())\n",[1176,2142,2143],{"class":1178,"line":1413},[1176,2144,2145],{"class":1342},"\u002F\u002F → \"Hello, world\"\n",[1176,2147,2148,2150,2152,2154,2156,2158,2160,2162,2164,2166,2168,2170,2172,2175,2177,2179,2181,2183],{"class":1178,"line":1430},[1176,2149,2110],{"class":1190},[1176,2151,1468],{"class":1186},[1176,2153,2115],{"class":1383},[1176,2155,2118],{"class":1190},[1176,2157,1468],{"class":1186},[1176,2159,2016],{"class":1383},[1176,2161,1386],{"class":1190},[1176,2163,1407],{"class":1186},[1176,2165,2023],{"class":1203},[1176,2167,1407],{"class":1186},[1176,2169,1986],{"class":1190},[1176,2171,1468],{"class":1186},[1176,2173,2174],{"class":1383},"get",[1176,2176,1386],{"class":1190},[1176,2178,1407],{"class":1186},[1176,2180,2039],{"class":1203},[1176,2182,1407],{"class":1186},[1176,2184,2185],{"class":1190},"))\n",[1176,2187,2188],{"class":1178,"line":1478},[1176,2189,2190],{"class":1342},"\u002F\u002F → \"alice\"\n",[941,2192,2193,2194,2196,2197,2200,2201,2203,2204,1051,2206,2208],{},"Without ",[953,2195,955],{},", the first ",[953,2198,2199],{},"putYDoc()"," on a ",[953,2202,1788],{}," collection rejects with an error pointing at ",[953,2205,955],{},[953,2207,1054],{}," — features you have not opted into fail loudly.",[941,2210,2211,2212,2215,2216,2219],{},"For structured (non-rich-text) records, the two other CRDT modes need no extra package: declare ",[953,2213,2214],{},"vault.collection\u003CT>('name', { crdt: 'lww-map' })"," (last-writer-wins per field) or ",[953,2217,2218],{},"{ crdt: 'rga' }"," (replicated growable array).",[1021,2221,2223],{"id":2222},"two-collaborators-edit-concurrently-the-merge-converges","Two collaborators edit concurrently — the merge converges",[941,2225,2226],{},"Two people fork the same document, edit independently, and exchange Yjs update buffers. The CRDT guarantees both end up with the identical merged text — no lost writes, no manual conflict dialog.",[1167,2228,2230],{"className":1169,"code":2229,"language":1171,"meta":1172,"style":1172},"import * as Y from 'yjs'\n\n\u002F\u002F Seed a baseline both collaborators fork from.\nconst baseline = await docs.getYDoc('doc-shared')\nbaseline.getText('body').insert(0, 'Hello')\nawait docs.putYDoc('doc-shared', baseline)\n\n\u002F\u002F Alice — appends.\nconst docA = await docs.getYDoc('doc-shared')\ndocA.getText('body').insert(docA.getText('body').length, ' from Alice')\n\n\u002F\u002F Bob — independently prepends.\nconst docB = await docs.getYDoc('doc-shared')\ndocB.getText('body').insert(0, 'Hi! ')\n\n\u002F\u002F Merge by exchanging update buffers — the CRDT contract.\nY.applyUpdate(docA, Y.encodeStateAsUpdate(docB))\nY.applyUpdate(docB, Y.encodeStateAsUpdate(docA))\n\nconsole.log(docA.getText('body').toString())\n\u002F\u002F → \"Hi! Hello from Alice\"\nconsole.log(docA.getText('body').toString() === docB.getText('body').toString())\n\u002F\u002F → true\n\n\u002F\u002F Persist the merged state — it round-trips through encryption intact.\nawait docs.putYDoc('doc-shared', docA)\n",[953,2231,2232,2253,2257,2262,2290,2328,2351,2355,2360,2387,2443,2447,2452,2479,2517,2521,2526,2551,2573,2577,2607,2612,2668,2673,2677,2682],{"__ignoreMap":1172},[1176,2233,2234,2236,2238,2241,2244,2247,2249,2251],{"class":1178,"line":1179},[1176,2235,1183],{"class":1182},[1176,2237,1693],{"class":1186},[1176,2239,2240],{"class":1182}," as",[1176,2242,2243],{"class":1190}," Y ",[1176,2245,2246],{"class":1182},"from",[1176,2248,1200],{"class":1186},[1176,2250,287],{"class":1203},[1176,2252,1207],{"class":1186},[1176,2254,2255],{"class":1178,"line":1210},[1176,2256,1336],{"emptyLinePlaceholder":1335},[1176,2258,2259],{"class":1178,"line":1230},[1176,2260,2261],{"class":1342},"\u002F\u002F Seed a baseline both collaborators fork from.\n",[1176,2263,2264,2266,2269,2271,2273,2275,2277,2279,2281,2283,2286,2288],{"class":1178,"line":1250},[1176,2265,1374],{"class":1373},[1176,2267,2268],{"class":1190}," baseline ",[1176,2270,1380],{"class":1186},[1176,2272,1502],{"class":1182},[1176,2274,1945],{"class":1190},[1176,2276,1468],{"class":1186},[1176,2278,983],{"class":1383},[1176,2280,1386],{"class":1190},[1176,2282,1407],{"class":1186},[1176,2284,2285],{"class":1203},"doc-shared",[1176,2287,1407],{"class":1186},[1176,2289,1484],{"class":1190},[1176,2291,2292,2295,2297,2299,2301,2303,2305,2307,2309,2311,2313,2315,2317,2319,2321,2324,2326],{"class":1178,"line":1270},[1176,2293,2294],{"class":1190},"baseline",[1176,2296,1468],{"class":1186},[1176,2298,1974],{"class":1383},[1176,2300,1386],{"class":1190},[1176,2302,1407],{"class":1186},[1176,2304,1981],{"class":1203},[1176,2306,1407],{"class":1186},[1176,2308,1986],{"class":1190},[1176,2310,1468],{"class":1186},[1176,2312,1991],{"class":1383},[1176,2314,1386],{"class":1190},[1176,2316,1996],{"class":1689},[1176,2318,1523],{"class":1186},[1176,2320,1200],{"class":1186},[1176,2322,2323],{"class":1203},"Hello",[1176,2325,1407],{"class":1186},[1176,2327,1484],{"class":1190},[1176,2329,2330,2332,2334,2336,2338,2340,2342,2344,2346,2348],{"class":1178,"line":1290},[1176,2331,1450],{"class":1182},[1176,2333,1945],{"class":1190},[1176,2335,1468],{"class":1186},[1176,2337,987],{"class":1383},[1176,2339,1386],{"class":1190},[1176,2341,1407],{"class":1186},[1176,2343,2285],{"class":1203},[1176,2345,1407],{"class":1186},[1176,2347,1523],{"class":1186},[1176,2349,2350],{"class":1190}," baseline)\n",[1176,2352,2353],{"class":1178,"line":1311},[1176,2354,1336],{"emptyLinePlaceholder":1335},[1176,2356,2357],{"class":1178,"line":1332},[1176,2358,2359],{"class":1342},"\u002F\u002F Alice — appends.\n",[1176,2361,2362,2364,2367,2369,2371,2373,2375,2377,2379,2381,2383,2385],{"class":1178,"line":1339},[1176,2363,1374],{"class":1373},[1176,2365,2366],{"class":1190}," docA ",[1176,2368,1380],{"class":1186},[1176,2370,1502],{"class":1182},[1176,2372,1945],{"class":1190},[1176,2374,1468],{"class":1186},[1176,2376,983],{"class":1383},[1176,2378,1386],{"class":1190},[1176,2380,1407],{"class":1186},[1176,2382,2285],{"class":1203},[1176,2384,1407],{"class":1186},[1176,2386,1484],{"class":1190},[1176,2388,2389,2392,2394,2396,2398,2400,2402,2404,2406,2408,2410,2413,2415,2417,2419,2421,2423,2425,2427,2429,2432,2434,2436,2439,2441],{"class":1178,"line":1346},[1176,2390,2391],{"class":1190},"docA",[1176,2393,1468],{"class":1186},[1176,2395,1974],{"class":1383},[1176,2397,1386],{"class":1190},[1176,2399,1407],{"class":1186},[1176,2401,1981],{"class":1203},[1176,2403,1407],{"class":1186},[1176,2405,1986],{"class":1190},[1176,2407,1468],{"class":1186},[1176,2409,1991],{"class":1383},[1176,2411,2412],{"class":1190},"(docA",[1176,2414,1468],{"class":1186},[1176,2416,1974],{"class":1383},[1176,2418,1386],{"class":1190},[1176,2420,1407],{"class":1186},[1176,2422,1981],{"class":1203},[1176,2424,1407],{"class":1186},[1176,2426,1986],{"class":1190},[1176,2428,1468],{"class":1186},[1176,2430,2431],{"class":1190},"length",[1176,2433,1523],{"class":1186},[1176,2435,1200],{"class":1186},[1176,2437,2438],{"class":1203}," from Alice",[1176,2440,1407],{"class":1186},[1176,2442,1484],{"class":1190},[1176,2444,2445],{"class":1178,"line":1352},[1176,2446,1336],{"emptyLinePlaceholder":1335},[1176,2448,2449],{"class":1178,"line":1358},[1176,2450,2451],{"class":1342},"\u002F\u002F Bob — independently prepends.\n",[1176,2453,2454,2456,2459,2461,2463,2465,2467,2469,2471,2473,2475,2477],{"class":1178,"line":1364},[1176,2455,1374],{"class":1373},[1176,2457,2458],{"class":1190}," docB ",[1176,2460,1380],{"class":1186},[1176,2462,1502],{"class":1182},[1176,2464,1945],{"class":1190},[1176,2466,1468],{"class":1186},[1176,2468,983],{"class":1383},[1176,2470,1386],{"class":1190},[1176,2472,1407],{"class":1186},[1176,2474,2285],{"class":1203},[1176,2476,1407],{"class":1186},[1176,2478,1484],{"class":1190},[1176,2480,2481,2484,2486,2488,2490,2492,2494,2496,2498,2500,2502,2504,2506,2508,2510,2513,2515],{"class":1178,"line":1370},[1176,2482,2483],{"class":1190},"docB",[1176,2485,1468],{"class":1186},[1176,2487,1974],{"class":1383},[1176,2489,1386],{"class":1190},[1176,2491,1407],{"class":1186},[1176,2493,1981],{"class":1203},[1176,2495,1407],{"class":1186},[1176,2497,1986],{"class":1190},[1176,2499,1468],{"class":1186},[1176,2501,1991],{"class":1383},[1176,2503,1386],{"class":1190},[1176,2505,1996],{"class":1689},[1176,2507,1523],{"class":1186},[1176,2509,1200],{"class":1186},[1176,2511,2512],{"class":1203},"Hi! ",[1176,2514,1407],{"class":1186},[1176,2516,1484],{"class":1190},[1176,2518,2519],{"class":1178,"line":1392},[1176,2520,1336],{"emptyLinePlaceholder":1335},[1176,2522,2523],{"class":1178,"line":1413},[1176,2524,2525],{"class":1342},"\u002F\u002F Merge by exchanging update buffers — the CRDT contract.\n",[1176,2527,2528,2531,2533,2536,2538,2540,2543,2545,2548],{"class":1178,"line":1430},[1176,2529,2530],{"class":1190},"Y",[1176,2532,1468],{"class":1186},[1176,2534,2535],{"class":1383},"applyUpdate",[1176,2537,2412],{"class":1190},[1176,2539,1523],{"class":1186},[1176,2541,2542],{"class":1190}," Y",[1176,2544,1468],{"class":1186},[1176,2546,2547],{"class":1383},"encodeStateAsUpdate",[1176,2549,2550],{"class":1190},"(docB))\n",[1176,2552,2553,2555,2557,2559,2562,2564,2566,2568,2570],{"class":1178,"line":1478},[1176,2554,2530],{"class":1190},[1176,2556,1468],{"class":1186},[1176,2558,2535],{"class":1383},[1176,2560,2561],{"class":1190},"(docB",[1176,2563,1523],{"class":1186},[1176,2565,2542],{"class":1190},[1176,2567,1468],{"class":1186},[1176,2569,2547],{"class":1383},[1176,2571,2572],{"class":1190},"(docA))\n",[1176,2574,2575],{"class":1178,"line":1487},[1176,2576,1336],{"emptyLinePlaceholder":1335},[1176,2578,2579,2581,2583,2585,2587,2589,2591,2593,2595,2597,2599,2601,2603,2605],{"class":1178,"line":1492},[1176,2580,2110],{"class":1190},[1176,2582,1468],{"class":1186},[1176,2584,2115],{"class":1383},[1176,2586,2412],{"class":1190},[1176,2588,1468],{"class":1186},[1176,2590,1974],{"class":1383},[1176,2592,1386],{"class":1190},[1176,2594,1407],{"class":1186},[1176,2596,1981],{"class":1203},[1176,2598,1407],{"class":1186},[1176,2600,1986],{"class":1190},[1176,2602,1468],{"class":1186},[1176,2604,2137],{"class":1383},[1176,2606,2140],{"class":1190},[1176,2608,2609],{"class":1178,"line":1511},[1176,2610,2611],{"class":1342},"\u002F\u002F → \"Hi! Hello from Alice\"\n",[1176,2613,2614,2616,2618,2620,2622,2624,2626,2628,2630,2632,2634,2636,2638,2640,2642,2645,2648,2650,2652,2654,2656,2658,2660,2662,2664,2666],{"class":1178,"line":1529},[1176,2615,2110],{"class":1190},[1176,2617,1468],{"class":1186},[1176,2619,2115],{"class":1383},[1176,2621,2412],{"class":1190},[1176,2623,1468],{"class":1186},[1176,2625,1974],{"class":1383},[1176,2627,1386],{"class":1190},[1176,2629,1407],{"class":1186},[1176,2631,1981],{"class":1203},[1176,2633,1407],{"class":1186},[1176,2635,1986],{"class":1190},[1176,2637,1468],{"class":1186},[1176,2639,2137],{"class":1383},[1176,2641,1918],{"class":1190},[1176,2643,2644],{"class":1186},"===",[1176,2646,2647],{"class":1190}," docB",[1176,2649,1468],{"class":1186},[1176,2651,1974],{"class":1383},[1176,2653,1386],{"class":1190},[1176,2655,1407],{"class":1186},[1176,2657,1981],{"class":1203},[1176,2659,1407],{"class":1186},[1176,2661,1986],{"class":1190},[1176,2663,1468],{"class":1186},[1176,2665,2137],{"class":1383},[1176,2667,2140],{"class":1190},[1176,2669,2670],{"class":1178,"line":1567},[1176,2671,2672],{"class":1342},"\u002F\u002F → true\n",[1176,2674,2675],{"class":1178,"line":1584},[1176,2676,1336],{"emptyLinePlaceholder":1335},[1176,2678,2679],{"class":1178,"line":1604},[1176,2680,2681],{"class":1342},"\u002F\u002F Persist the merged state — it round-trips through encryption intact.\n",[1176,2683,2684,2686,2688,2690,2692,2694,2696,2698,2700,2702],{"class":1178,"line":1609},[1176,2685,1450],{"class":1182},[1176,2687,1945],{"class":1190},[1176,2689,1468],{"class":1186},[1176,2691,987],{"class":1383},[1176,2693,1386],{"class":1190},[1176,2695,1407],{"class":1186},[1176,2697,2285],{"class":1203},[1176,2699,1407],{"class":1186},[1176,2701,1523],{"class":1186},[1176,2703,2704],{"class":1190}," docA)\n",[941,2706,2707,2710,2711,2715],{},[953,2708,2709],{},"docs.applyUpdate(id, update)"," does the same merge against the ",[2712,2713,2714],"em",{},"stored"," state in one call: it loads the record, applies the incoming update buffer, and persists the merged result.",[1021,2717,2719],{"id":2718},"replicate-between-devices-push-and-pull","Replicate between devices — push and pull",[941,2721,2722,2723,2726,2727,2730],{},"Each device runs the setup above against the same remote. ",[953,2724,2725],{},"db.push(vault)"," uploads locally-changed records; ",[953,2728,2729],{},"db.pull(vault)"," downloads remote changes.",[1167,2732,2734],{"className":1169,"code":2733,"language":1171,"meta":1172,"style":1172},"\u002F\u002F Device A\nconst docA2 = await docs.getYDoc('doc-1')\ndocA2.getText('body').insert(0, 'Edited on device A. ')\nawait docs.putYDoc('doc-1', docA2)\n\n\u002F\u002F put() marks the record dirty on a microtask — let it settle before pushing.\nawait new Promise((resolve) => setTimeout(resolve, 0))\n\nconsole.log(await db.push('shared'))\n\u002F\u002F → { pushed: 1, conflicts: [], errors: [] }\n",[953,2735,2736,2741,2768,2806,2829,2833,2838,2874,2878,2907],{"__ignoreMap":1172},[1176,2737,2738],{"class":1178,"line":1179},[1176,2739,2740],{"class":1342},"\u002F\u002F Device A\n",[1176,2742,2743,2745,2748,2750,2752,2754,2756,2758,2760,2762,2764,2766],{"class":1178,"line":1210},[1176,2744,1374],{"class":1373},[1176,2746,2747],{"class":1190}," docA2 ",[1176,2749,1380],{"class":1186},[1176,2751,1502],{"class":1182},[1176,2753,1945],{"class":1190},[1176,2755,1468],{"class":1186},[1176,2757,983],{"class":1383},[1176,2759,1386],{"class":1190},[1176,2761,1407],{"class":1186},[1176,2763,1956],{"class":1203},[1176,2765,1407],{"class":1186},[1176,2767,1484],{"class":1190},[1176,2769,2770,2773,2775,2777,2779,2781,2783,2785,2787,2789,2791,2793,2795,2797,2799,2802,2804],{"class":1178,"line":1230},[1176,2771,2772],{"class":1190},"docA2",[1176,2774,1468],{"class":1186},[1176,2776,1974],{"class":1383},[1176,2778,1386],{"class":1190},[1176,2780,1407],{"class":1186},[1176,2782,1981],{"class":1203},[1176,2784,1407],{"class":1186},[1176,2786,1986],{"class":1190},[1176,2788,1468],{"class":1186},[1176,2790,1991],{"class":1383},[1176,2792,1386],{"class":1190},[1176,2794,1996],{"class":1689},[1176,2796,1523],{"class":1186},[1176,2798,1200],{"class":1186},[1176,2800,2801],{"class":1203},"Edited on device A. ",[1176,2803,1407],{"class":1186},[1176,2805,1484],{"class":1190},[1176,2807,2808,2810,2812,2814,2816,2818,2820,2822,2824,2826],{"class":1178,"line":1250},[1176,2809,1450],{"class":1182},[1176,2811,1945],{"class":1190},[1176,2813,1468],{"class":1186},[1176,2815,987],{"class":1383},[1176,2817,1386],{"class":1190},[1176,2819,1407],{"class":1186},[1176,2821,1956],{"class":1203},[1176,2823,1407],{"class":1186},[1176,2825,1523],{"class":1186},[1176,2827,2828],{"class":1190}," docA2)\n",[1176,2830,2831],{"class":1178,"line":1270},[1176,2832,1336],{"emptyLinePlaceholder":1335},[1176,2834,2835],{"class":1178,"line":1290},[1176,2836,2837],{"class":1342},"\u002F\u002F put() marks the record dirty on a microtask — let it settle before pushing.\n",[1176,2839,2840,2842,2845,2849,2851,2853,2857,2859,2861,2864,2867,2869,2872],{"class":1178,"line":1311},[1176,2841,1450],{"class":1182},[1176,2843,2844],{"class":1186}," new",[1176,2846,2848],{"class":2847},"sBMFI"," Promise",[1176,2850,1386],{"class":1190},[1176,2852,1386],{"class":1186},[1176,2854,2856],{"class":2855},"sHdIc","resolve",[1176,2858,1986],{"class":1186},[1176,2860,1444],{"class":1373},[1176,2862,2863],{"class":1383}," setTimeout",[1176,2865,2866],{"class":1190},"(resolve",[1176,2868,1523],{"class":1186},[1176,2870,2871],{"class":1689}," 0",[1176,2873,2185],{"class":1190},[1176,2875,2876],{"class":1178,"line":1332},[1176,2877,1336],{"emptyLinePlaceholder":1335},[1176,2879,2880,2882,2884,2886,2888,2890,2892,2894,2897,2899,2901,2903,2905],{"class":1178,"line":1339},[1176,2881,2110],{"class":1190},[1176,2883,1468],{"class":1186},[1176,2885,2115],{"class":1383},[1176,2887,1386],{"class":1190},[1176,2889,1450],{"class":1182},[1176,2891,1841],{"class":1190},[1176,2893,1468],{"class":1186},[1176,2895,2896],{"class":1383},"push",[1176,2898,1386],{"class":1190},[1176,2900,1407],{"class":1186},[1176,2902,1853],{"class":1203},[1176,2904,1407],{"class":1186},[1176,2906,2185],{"class":1190},[1176,2908,2909],{"class":1178,"line":1346},[1176,2910,2911],{"class":1342},"\u002F\u002F → { pushed: 1, conflicts: [], errors: [] }\n",[1167,2913,2915],{"className":1169,"code":2914,"language":1171,"meta":1172,"style":1172},"\u002F\u002F Device B (same setup, same remote)\nconsole.log(await db.pull('shared'))\n\u002F\u002F → { pulled: 1, conflicts: [], errors: [] }\n\nconst latest = await docs.getYDoc('doc-1')\nconsole.log(latest.getText('body').toString())\n\u002F\u002F → \"Edited on device A. Hello, world\"\n",[953,2916,2917,2922,2951,2956,2960,2987,3018],{"__ignoreMap":1172},[1176,2918,2919],{"class":1178,"line":1179},[1176,2920,2921],{"class":1342},"\u002F\u002F Device B (same setup, same remote)\n",[1176,2923,2924,2926,2928,2930,2932,2934,2936,2938,2941,2943,2945,2947,2949],{"class":1178,"line":1210},[1176,2925,2110],{"class":1190},[1176,2927,1468],{"class":1186},[1176,2929,2115],{"class":1383},[1176,2931,1386],{"class":1190},[1176,2933,1450],{"class":1182},[1176,2935,1841],{"class":1190},[1176,2937,1468],{"class":1186},[1176,2939,2940],{"class":1383},"pull",[1176,2942,1386],{"class":1190},[1176,2944,1407],{"class":1186},[1176,2946,1853],{"class":1203},[1176,2948,1407],{"class":1186},[1176,2950,2185],{"class":1190},[1176,2952,2953],{"class":1178,"line":1230},[1176,2954,2955],{"class":1342},"\u002F\u002F → { pulled: 1, conflicts: [], errors: [] }\n",[1176,2957,2958],{"class":1178,"line":1250},[1176,2959,1336],{"emptyLinePlaceholder":1335},[1176,2961,2962,2964,2967,2969,2971,2973,2975,2977,2979,2981,2983,2985],{"class":1178,"line":1270},[1176,2963,1374],{"class":1373},[1176,2965,2966],{"class":1190}," latest ",[1176,2968,1380],{"class":1186},[1176,2970,1502],{"class":1182},[1176,2972,1945],{"class":1190},[1176,2974,1468],{"class":1186},[1176,2976,983],{"class":1383},[1176,2978,1386],{"class":1190},[1176,2980,1407],{"class":1186},[1176,2982,1956],{"class":1203},[1176,2984,1407],{"class":1186},[1176,2986,1484],{"class":1190},[1176,2988,2989,2991,2993,2995,2998,3000,3002,3004,3006,3008,3010,3012,3014,3016],{"class":1178,"line":1290},[1176,2990,2110],{"class":1190},[1176,2992,1468],{"class":1186},[1176,2994,2115],{"class":1383},[1176,2996,2997],{"class":1190},"(latest",[1176,2999,1468],{"class":1186},[1176,3001,1974],{"class":1383},[1176,3003,1386],{"class":1190},[1176,3005,1407],{"class":1186},[1176,3007,1981],{"class":1203},[1176,3009,1407],{"class":1186},[1176,3011,1986],{"class":1190},[1176,3013,1468],{"class":1186},[1176,3015,2137],{"class":1383},[1176,3017,2140],{"class":1190},[1176,3019,3020],{"class":1178,"line":1311},[1176,3021,3022],{"class":1342},"\u002F\u002F → \"Edited on device A. Hello, world\"\n",[941,3024,3025,3026,3029,3030,3033],{},"If both devices changed the ",[2712,3027,3028],{},"same"," record before syncing, the ",[953,3031,3032],{},"conflicts"," array is non-empty and the conflict rules below decide the winner.",[1021,3035,3037],{"id":3036},"live-presence-see-who-else-is-here","Live presence — see who else is here",[941,3039,3040,3042,3043,3045],{},[953,3041,1090],{}," (enabled by ",[953,3044,959],{},") gives you an encrypted ephemeral channel for awareness data — cursors, selections, \"Bob is typing…\".",[1167,3047,3049],{"className":1169,"code":3048,"language":1171,"meta":1172,"style":1172},"const presence = vault\n  .collection('docs')\n  .presence\u003C{ cursor: { x: number; y: number } }>()\n\n\u002F\u002F Broadcast my cursor (call again whenever it moves).\nawait presence.update({ cursor: { x: 120, y: 340 } })\n\n\u002F\u002F Subscribe to peers — the callback receives all active peers,\n\u002F\u002F excluding yourself and anyone stale (default: silent for 30 s).\nconst unsubscribe = presence.subscribe((peers) => {\n  for (const peer of peers) {\n    console.log(`${peer.userId}: cursor at`, peer.payload.cursor)\n  }\n})\n\u002F\u002F → \"bob: cursor at { x: 512, y: 88 }\"   (fires when bob calls update())\n\n\u002F\u002F When the document view unmounts:\nunsubscribe()\npresence.stop()\n",[953,3050,3051,3063,3081,3124,3128,3133,3178,3182,3187,3192,3221,3244,3289,3294,3300,3305,3309,3314,3321],{"__ignoreMap":1172},[1176,3052,3053,3055,3058,3060],{"class":1178,"line":1179},[1176,3054,1374],{"class":1373},[1176,3056,3057],{"class":1190}," presence ",[1176,3059,1380],{"class":1186},[1176,3061,3062],{"class":1190}," vault\n",[1176,3064,3065,3068,3071,3073,3075,3077,3079],{"class":1178,"line":1210},[1176,3066,3067],{"class":1186},"  .",[1176,3069,3070],{"class":1383},"collection",[1176,3072,1386],{"class":1190},[1176,3074,1407],{"class":1186},[1176,3076,1882],{"class":1203},[1176,3078,1407],{"class":1186},[1176,3080,1484],{"class":1190},[1176,3082,3083,3085,3088,3091,3094,3096,3098,3101,3103,3106,3109,3112,3114,3116,3118,3121],{"class":1178,"line":1230},[1176,3084,3067],{"class":1186},[1176,3086,3087],{"class":1383},"presence",[1176,3089,3090],{"class":1186},"\u003C{",[1176,3092,3093],{"class":1395}," cursor",[1176,3095,1399],{"class":1186},[1176,3097,1187],{"class":1186},[1176,3099,3100],{"class":1395}," x",[1176,3102,1399],{"class":1186},[1176,3104,3105],{"class":2847}," number",[1176,3107,3108],{"class":1186},";",[1176,3110,3111],{"class":1395}," y",[1176,3113,1399],{"class":1186},[1176,3115,3105],{"class":2847},[1176,3117,1194],{"class":1186},[1176,3119,3120],{"class":1186}," }>",[1176,3122,3123],{"class":1190},"()\n",[1176,3125,3126],{"class":1178,"line":1250},[1176,3127,1336],{"emptyLinePlaceholder":1335},[1176,3129,3130],{"class":1178,"line":1270},[1176,3131,3132],{"class":1342},"\u002F\u002F Broadcast my cursor (call again whenever it moves).\n",[1176,3134,3135,3137,3140,3142,3145,3147,3150,3152,3154,3156,3158,3160,3163,3165,3167,3169,3172,3174,3176],{"class":1178,"line":1290},[1176,3136,1450],{"class":1182},[1176,3138,3139],{"class":1190}," presence",[1176,3141,1468],{"class":1186},[1176,3143,3144],{"class":1383},"update",[1176,3146,1386],{"class":1190},[1176,3148,3149],{"class":1186},"{",[1176,3151,3093],{"class":1395},[1176,3153,1399],{"class":1186},[1176,3155,1187],{"class":1186},[1176,3157,3100],{"class":1395},[1176,3159,1399],{"class":1186},[1176,3161,3162],{"class":1689}," 120",[1176,3164,1523],{"class":1186},[1176,3166,3111],{"class":1395},[1176,3168,1399],{"class":1186},[1176,3170,3171],{"class":1689}," 340",[1176,3173,1194],{"class":1186},[1176,3175,1194],{"class":1186},[1176,3177,1484],{"class":1190},[1176,3179,3180],{"class":1178,"line":1311},[1176,3181,1336],{"emptyLinePlaceholder":1335},[1176,3183,3184],{"class":1178,"line":1332},[1176,3185,3186],{"class":1342},"\u002F\u002F Subscribe to peers — the callback receives all active peers,\n",[1176,3188,3189],{"class":1178,"line":1339},[1176,3190,3191],{"class":1342},"\u002F\u002F excluding yourself and anyone stale (default: silent for 30 s).\n",[1176,3193,3194,3196,3199,3201,3203,3205,3208,3210,3212,3215,3217,3219],{"class":1178,"line":1346},[1176,3195,1374],{"class":1373},[1176,3197,3198],{"class":1190}," unsubscribe ",[1176,3200,1380],{"class":1186},[1176,3202,3139],{"class":1190},[1176,3204,1468],{"class":1186},[1176,3206,3207],{"class":1383},"subscribe",[1176,3209,1386],{"class":1190},[1176,3211,1386],{"class":1186},[1176,3213,3214],{"class":2855},"peers",[1176,3216,1986],{"class":1186},[1176,3218,1444],{"class":1373},[1176,3220,1678],{"class":1186},[1176,3222,3223,3226,3228,3230,3233,3236,3239,3242],{"class":1178,"line":1352},[1176,3224,3225],{"class":1182},"  for",[1176,3227,1447],{"class":1395},[1176,3229,1374],{"class":1373},[1176,3231,3232],{"class":1190}," peer",[1176,3234,3235],{"class":1186}," of",[1176,3237,3238],{"class":1190}," peers",[1176,3240,3241],{"class":1395},") ",[1176,3243,1389],{"class":1186},[1176,3245,3246,3249,3251,3253,3255,3258,3260,3262,3265,3267,3270,3273,3275,3277,3279,3282,3284,3287],{"class":1178,"line":1358},[1176,3247,3248],{"class":1190},"    console",[1176,3250,1468],{"class":1186},[1176,3252,2115],{"class":1383},[1176,3254,1386],{"class":1395},[1176,3256,3257],{"class":1186},"`${",[1176,3259,201],{"class":1190},[1176,3261,1468],{"class":1186},[1176,3263,3264],{"class":1190},"userId",[1176,3266,1481],{"class":1186},[1176,3268,3269],{"class":1203},": cursor at",[1176,3271,3272],{"class":1186},"`",[1176,3274,1523],{"class":1186},[1176,3276,3232],{"class":1190},[1176,3278,1468],{"class":1186},[1176,3280,3281],{"class":1190},"payload",[1176,3283,1468],{"class":1186},[1176,3285,3286],{"class":1190},"cursor",[1176,3288,1484],{"class":1395},[1176,3290,3291],{"class":1178,"line":1364},[1176,3292,3293],{"class":1186},"  }\n",[1176,3295,3296,3298],{"class":1178,"line":1370},[1176,3297,1481],{"class":1186},[1176,3299,1484],{"class":1190},[1176,3301,3302],{"class":1178,"line":1392},[1176,3303,3304],{"class":1342},"\u002F\u002F → \"bob: cursor at { x: 512, y: 88 }\"   (fires when bob calls update())\n",[1176,3306,3307],{"class":1178,"line":1413},[1176,3308,1336],{"emptyLinePlaceholder":1335},[1176,3310,3311],{"class":1178,"line":1430},[1176,3312,3313],{"class":1342},"\u002F\u002F When the document view unmounts:\n",[1176,3315,3316,3319],{"class":1178,"line":1478},[1176,3317,3318],{"class":1383},"unsubscribe",[1176,3320,3123],{"class":1190},[1176,3322,3323,3325,3327,3330],{"class":1178,"line":1487},[1176,3324,3087],{"class":1190},[1176,3326,1468],{"class":1186},[1176,3328,3329],{"class":1383},"stop",[1176,3331,3123],{"class":1190},[941,3333,3334,3335,3338],{},"The presence channel key is derived (via HKDF) from the collection's DEK — the data-encryption key that encrypts the collection's records (see ",[1015,3336,21],{"href":3337},"..\u002Fcore\u002Fnoydb\u002Fenclave"," for the full key hierarchy). Two consequences:",[3340,3341,3342,3346],"ul",{},[3343,3344,3345],"li",{},"The remote store never sees which user is doing what — presence payloads are ciphertext to it.",[3343,3347,3348],{},"Revoked users automatically lose presence access on the next DEK rotation.",[941,3350,3351,3352,1083,3355,3358,3359,3362,3363,3366],{},"Transport adapts to the store: adapters that implement pub\u002Fsub (",[953,3353,3354],{},"presencePublish",[953,3356,3357],{},"presenceSubscribe",") get real-time delivery; all others fall back to polling a reserved ",[953,3360,3361],{},"_presence_\u003Ccollection>"," collection (default poll interval: 5 s, tunable via ",[953,3364,3365],{},"presence({ pollIntervalMs, staleMs })",").",[1021,3368,3370],{"id":3369},"granting-access-to-a-collaborator","Granting access to a collaborator",[941,3372,3373,3042,3375,3377],{},[953,3374,1105],{},[953,3376,962],{},") wraps the vault's keys for a new user, who then unlocks with their own secret.",[1167,3379,3381],{"className":1169,"code":3380,"language":1171,"meta":1172,"style":1172},"await db.grant('shared', {\n  userId: 'bob',\n  displayName: 'Bob',\n  role: 'operator',\n  secret: 'a-secret-bob-will-change',\n  permissions: { docs: 'rw' },   \u002F\u002F per-collection: 'rw' or 'ro'\n})\n\nconsole.log((await db.listUsers('shared')).map((u) => u.userId))\n\u002F\u002F → [\"alice\", \"bob\"]\n",[953,3382,3383,3406,3422,3438,3454,3469,3494,3500,3504,3558],{"__ignoreMap":1172},[1176,3384,3385,3387,3389,3391,3394,3396,3398,3400,3402,3404],{"class":1178,"line":1179},[1176,3386,1450],{"class":1182},[1176,3388,1841],{"class":1190},[1176,3390,1468],{"class":1186},[1176,3392,3393],{"class":1383},"grant",[1176,3395,1386],{"class":1190},[1176,3397,1407],{"class":1186},[1176,3399,1853],{"class":1203},[1176,3401,1407],{"class":1186},[1176,3403,1523],{"class":1186},[1176,3405,1678],{"class":1186},[1176,3407,3408,3411,3413,3415,3418,3420],{"class":1178,"line":1210},[1176,3409,3410],{"class":1395},"  userId",[1176,3412,1399],{"class":1186},[1176,3414,1200],{"class":1186},[1176,3416,3417],{"class":1203},"bob",[1176,3419,1407],{"class":1186},[1176,3421,1410],{"class":1186},[1176,3423,3424,3427,3429,3431,3434,3436],{"class":1178,"line":1230},[1176,3425,3426],{"class":1395},"  displayName",[1176,3428,1399],{"class":1186},[1176,3430,1200],{"class":1186},[1176,3432,3433],{"class":1203},"Bob",[1176,3435,1407],{"class":1186},[1176,3437,1410],{"class":1186},[1176,3439,3440,3443,3445,3447,3450,3452],{"class":1178,"line":1250},[1176,3441,3442],{"class":1395},"  role",[1176,3444,1399],{"class":1186},[1176,3446,1200],{"class":1186},[1176,3448,3449],{"class":1203},"operator",[1176,3451,1407],{"class":1186},[1176,3453,1410],{"class":1186},[1176,3455,3456,3458,3460,3462,3465,3467],{"class":1178,"line":1270},[1176,3457,1587],{"class":1395},[1176,3459,1399],{"class":1186},[1176,3461,1200],{"class":1186},[1176,3463,3464],{"class":1203},"a-secret-bob-will-change",[1176,3466,1407],{"class":1186},[1176,3468,1410],{"class":1186},[1176,3470,3471,3474,3476,3478,3480,3482,3484,3487,3489,3491],{"class":1178,"line":1290},[1176,3472,3473],{"class":1395},"  permissions",[1176,3475,1399],{"class":1186},[1176,3477,1187],{"class":1186},[1176,3479,1945],{"class":1395},[1176,3481,1399],{"class":1186},[1176,3483,1200],{"class":1186},[1176,3485,3486],{"class":1203},"rw",[1176,3488,1407],{"class":1186},[1176,3490,1561],{"class":1186},[1176,3492,3493],{"class":1342},"   \u002F\u002F per-collection: 'rw' or 'ro'\n",[1176,3495,3496,3498],{"class":1178,"line":1311},[1176,3497,1481],{"class":1186},[1176,3499,1484],{"class":1190},[1176,3501,3502],{"class":1178,"line":1332},[1176,3503,1336],{"emptyLinePlaceholder":1335},[1176,3505,3506,3508,3510,3512,3515,3517,3519,3521,3524,3526,3528,3530,3532,3534,3536,3539,3541,3543,3546,3548,3550,3553,3555],{"class":1178,"line":1339},[1176,3507,2110],{"class":1190},[1176,3509,1468],{"class":1186},[1176,3511,2115],{"class":1383},[1176,3513,3514],{"class":1190},"((",[1176,3516,1450],{"class":1182},[1176,3518,1841],{"class":1190},[1176,3520,1468],{"class":1186},[1176,3522,3523],{"class":1383},"listUsers",[1176,3525,1386],{"class":1190},[1176,3527,1407],{"class":1186},[1176,3529,1853],{"class":1203},[1176,3531,1407],{"class":1186},[1176,3533,1465],{"class":1190},[1176,3535,1468],{"class":1186},[1176,3537,3538],{"class":1383},"map",[1176,3540,1386],{"class":1190},[1176,3542,1386],{"class":1186},[1176,3544,3545],{"class":2855},"u",[1176,3547,1986],{"class":1186},[1176,3549,1444],{"class":1373},[1176,3551,3552],{"class":1190}," u",[1176,3554,1468],{"class":1186},[1176,3556,3557],{"class":1190},"userId))\n",[1176,3559,3560],{"class":1178,"line":1346},[1176,3561,3562],{"class":1342},"\u002F\u002F → [\"alice\", \"bob\"]\n",[941,3564,3565,3566,1061,3569,1061,3572,1061,3575,1061,3577,1061,3580,1781,3583,3585,3586,3589,3590,1468],{},"Roles are ",[953,3567,3568],{},"owner",[953,3570,3571],{},"admin",[953,3573,3574],{},"custodian",[953,3576,3449],{},[953,3578,3579],{},"viewer",[953,3581,3582],{},"client",[953,3584,1105],{}," does not check the new secret's strength by default — it accepts whatever string you pass for ",[953,3587,3588],{},"secret",". If your app needs a minimum-strength policy at invite time, validate the secret yourself before calling ",[953,3591,3592],{},"grant()",[941,3594,3595],{},"Bob unlocks the same vault with his own credentials:",[1167,3597,3599],{"className":1169,"code":3598,"language":1171,"meta":1172,"style":1172},"const bobDb = await createNoydb({\n  store: toBrowserIdb(),\n  sync: { store: remote, role: 'sync-peer' },\n  user: 'bob',\n  secret: 'a-secret-bob-will-change',\n  crdtStrategy: withCrdt(),\n  syncStrategy: withSync(),\n})\n",[953,3600,3601,3618,3630,3659,3673,3687,3699,3711],{"__ignoreMap":1172},[1176,3602,3603,3605,3608,3610,3612,3614,3616],{"class":1178,"line":1179},[1176,3604,1374],{"class":1373},[1176,3606,3607],{"class":1190}," bobDb ",[1176,3609,1380],{"class":1186},[1176,3611,1502],{"class":1182},[1176,3613,1191],{"class":1383},[1176,3615,1386],{"class":1190},[1176,3617,1389],{"class":1186},[1176,3619,3620,3622,3624,3626,3628],{"class":1178,"line":1210},[1176,3621,1514],{"class":1395},[1176,3623,1399],{"class":1186},[1176,3625,1297],{"class":1383},[1176,3627,1473],{"class":1190},[1176,3629,1410],{"class":1186},[1176,3631,3632,3634,3636,3638,3640,3642,3644,3646,3648,3650,3652,3654,3656],{"class":1178,"line":1230},[1176,3633,1532],{"class":1395},[1176,3635,1399],{"class":1186},[1176,3637,1187],{"class":1186},[1176,3639,1539],{"class":1395},[1176,3641,1399],{"class":1186},[1176,3643,1544],{"class":1190},[1176,3645,1523],{"class":1186},[1176,3647,1549],{"class":1395},[1176,3649,1399],{"class":1186},[1176,3651,1200],{"class":1186},[1176,3653,1556],{"class":1203},[1176,3655,1407],{"class":1186},[1176,3657,3658],{"class":1186}," },\n",[1176,3660,3661,3663,3665,3667,3669,3671],{"class":1178,"line":1250},[1176,3662,1570],{"class":1395},[1176,3664,1399],{"class":1186},[1176,3666,1200],{"class":1186},[1176,3668,3417],{"class":1203},[1176,3670,1407],{"class":1186},[1176,3672,1410],{"class":1186},[1176,3674,3675,3677,3679,3681,3683,3685],{"class":1178,"line":1270},[1176,3676,1587],{"class":1395},[1176,3678,1399],{"class":1186},[1176,3680,1200],{"class":1186},[1176,3682,3464],{"class":1203},[1176,3684,1407],{"class":1186},[1176,3686,1410],{"class":1186},[1176,3688,3689,3691,3693,3695,3697],{"class":1178,"line":1290},[1176,3690,1612],{"class":1395},[1176,3692,1399],{"class":1186},[1176,3694,1217],{"class":1383},[1176,3696,1473],{"class":1190},[1176,3698,1410],{"class":1186},[1176,3700,3701,3703,3705,3707,3709],{"class":1178,"line":1311},[1176,3702,1626],{"class":1395},[1176,3704,1399],{"class":1186},[1176,3706,1237],{"class":1383},[1176,3708,1473],{"class":1190},[1176,3710,1410],{"class":1186},[1176,3712,3713,3715],{"class":1178,"line":1332},[1176,3714,1481],{"class":1186},[1176,3716,1484],{"class":1190},[941,3718,3719,3720,3723,3724,3366],{},"Secrets are only one unlock path — the ",[953,3721,3722],{},"@noy-db\u002Fon-*"," packages add WebAuthn, OIDC, magic links, TOTP, and more (see the ",[1015,3725,3727],{"href":3726},"..\u002Ffamilies\u002Fon\u002F","on- family",[1021,3729,3731],{"id":3730},"conflicts-what-wins-when-both-sides-changed","Conflicts — what wins when both sides changed?",[941,3733,3734,3735,3738,3739,3743],{},"Two knobs, at two levels. Both operate on the ",[944,3736,3737],{},"envelope"," — the single encrypted blob a record is stored as (see ",[1015,3740,3742],{"href":3741},"..\u002Fcore\u002F05-stores","Stores","); \"higher version wins\" etc. below means the envelope, not the decrypted fields.",[941,3745,3746,3752,3753,3756,3757,1468],{},[944,3747,3748,3749],{},"Db-level ",[953,3750,3751],{},"conflict"," (type ",[953,3754,3755],{},"ConflictStrategy",") applies to every collection unless overridden. Default: ",[953,3758,3759],{},"'version'",[1026,3761,3762,3772],{},[1029,3763,3764],{},[1032,3765,3766,3769],{},[1035,3767,3768],{},"Value",[1035,3770,3771],{},"Meaning",[1042,3773,3774,3788,3798,3808],{},[1032,3775,3776,3781],{},[1047,3777,3778,3780],{},[953,3779,3759],{}," (default)",[1047,3782,3783,3784,3787],{},"the envelope with the higher version counter ",[953,3785,3786],{},"_v"," wins",[1032,3789,3790,3795],{},[1047,3791,3792],{},[953,3793,3794],{},"'local-wins'",[1047,3796,3797],{},"keep the local envelope",[1032,3799,3800,3805],{},[1047,3801,3802],{},[953,3803,3804],{},"'remote-wins'",[1047,3806,3807],{},"keep the remote envelope",[1032,3809,3810,3815],{},[1047,3811,3812],{},[953,3813,3814],{},"(conflict) => 'local' | 'remote'",[1047,3816,3817],{},"decide per conflict",[941,3819,3820,3752,3826,3829],{},[944,3821,3822,3823],{},"Collection-level ",[953,3824,3825],{},"conflictPolicy",[953,3827,3828],{},"ConflictPolicy\u003CT>",") overrides the db-level strategy for one collection:",[1167,3831,3833],{"className":1169,"code":3832,"language":1171,"meta":1172,"style":1172},"interface Task {\n  id: string\n  title: string\n  done: boolean\n}\n\nconst tasks = vault.collection\u003CTask>('tasks', {\n  conflictPolicy: 'last-writer-wins',\n})\n",[953,3834,3835,3845,3855,3864,3874,3879,3883,3921,3937],{"__ignoreMap":1172},[1176,3836,3837,3840,3843],{"class":1178,"line":1179},[1176,3838,3839],{"class":1373},"interface",[1176,3841,3842],{"class":2847}," Task",[1176,3844,1678],{"class":1186},[1176,3846,3847,3850,3852],{"class":1178,"line":1210},[1176,3848,3849],{"class":1395},"  id",[1176,3851,1399],{"class":1186},[1176,3853,3854],{"class":2847}," string\n",[1176,3856,3857,3860,3862],{"class":1178,"line":1230},[1176,3858,3859],{"class":1395},"  title",[1176,3861,1399],{"class":1186},[1176,3863,3854],{"class":2847},[1176,3865,3866,3869,3871],{"class":1178,"line":1250},[1176,3867,3868],{"class":1395},"  done",[1176,3870,1399],{"class":1186},[1176,3872,3873],{"class":2847}," boolean\n",[1176,3875,3876],{"class":1178,"line":1270},[1176,3877,3878],{"class":1186},"}\n",[1176,3880,3881],{"class":1178,"line":1290},[1176,3882,1336],{"emptyLinePlaceholder":1335},[1176,3884,3885,3887,3890,3892,3895,3897,3899,3902,3905,3908,3910,3912,3915,3917,3919],{"class":1178,"line":1311},[1176,3886,1374],{"class":1373},[1176,3888,3889],{"class":1190}," tasks ",[1176,3891,1380],{"class":1186},[1176,3893,3894],{"class":1190}," vault",[1176,3896,1468],{"class":1186},[1176,3898,3070],{"class":1383},[1176,3900,3901],{"class":1186},"\u003C",[1176,3903,3904],{"class":2847},"Task",[1176,3906,3907],{"class":1186},">",[1176,3909,1386],{"class":1190},[1176,3911,1407],{"class":1186},[1176,3913,3914],{"class":1203},"tasks",[1176,3916,1407],{"class":1186},[1176,3918,1523],{"class":1186},[1176,3920,1678],{"class":1186},[1176,3922,3923,3926,3928,3930,3933,3935],{"class":1178,"line":1332},[1176,3924,3925],{"class":1395},"  conflictPolicy",[1176,3927,1399],{"class":1186},[1176,3929,1200],{"class":1186},[1176,3931,3932],{"class":1203},"last-writer-wins",[1176,3934,1407],{"class":1186},[1176,3936,1410],{"class":1186},[1176,3938,3939,3941],{"class":1178,"line":1339},[1176,3940,1481],{"class":1186},[1176,3942,1484],{"class":1190},[1026,3944,3945,3953],{},[1029,3946,3947],{},[1032,3948,3949,3951],{},[1035,3950,3768],{},[1035,3952,3771],{},[1042,3954,3955,3968,3981,3999],{},[1032,3956,3957,3962],{},[1047,3958,3959],{},[953,3960,3961],{},"'last-writer-wins'",[1047,3963,3964,3965,3787],{},"higher timestamp ",[953,3966,3967],{},"_ts",[1032,3969,3970,3975],{},[1047,3971,3972],{},[953,3973,3974],{},"'first-writer-wins'",[1047,3976,3977,3978,3980],{},"lower version ",[953,3979,3786],{}," wins (the earlier write is preserved)",[1032,3982,3983,3988],{},[1047,3984,3985],{},[953,3986,3987],{},"'manual'",[1047,3989,3990,3991,3994,3995,3998],{},"emits a ",[953,3992,3993],{},"sync:conflict"," event with a ",[953,3996,3997],{},"resolve(winner)"," callback — your UI decides",[1032,4000,4001,4006],{},[1047,4002,4003],{},[953,4004,4005],{},"(local, remote) => T",[1047,4007,4008],{},"a pure, synchronous custom merge over the decrypted records",[941,4010,4011,4014],{},[944,4012,4013],{},"CRDT collections"," resolve conflicts by merging instead of picking a winner — with one asymmetry:",[3340,4016,4017,4028],{},[3343,4018,4019,999,4021,4024,4025,4027],{},[953,4020,1060],{},[953,4022,4023],{},"crdt: 'rga'"," merge automatically inside the sync engine when ",[953,4026,1012],{}," hits a conflict. No writes are lost.",[3343,4029,4030,4032,4033,4035,4036,4038,4039,4041,4042,3366],{},[953,4031,1788],{}," cannot be merged by the sync engine (the core deliberately does not bundle the ",[953,4034,287],{}," package), so a conflicting envelope falls back to higher-",[953,4037,3786],{},"-wins. Converge in the client instead, by exchanging Yjs updates as shown above (",[953,4040,991],{}," or ",[953,4043,2709],{},[1021,4045,4047],{"id":4046},"limits-gotchas","Limits & gotchas",[3340,4049,4050,4062,4065,4079],{},[3343,4051,4052,4055,4056,4059,4060,1468],{},[953,4053,4054],{},"put()"," marks records dirty on a microtask — pushing in the same tick as the write can miss it. Yield once (",[953,4057,4058],{},"await new Promise((r) => setTimeout(r, 0))",") before an immediate ",[953,4061,1009],{},[3343,4063,4064],{},"Yjs merges happen in your app, not in the sync engine — plan for a \"pull, merge, push\" loop on each client (see above).",[3343,4066,4067,4068,4071,4072,4075,4076,4078],{},"Presence is ephemeral by design: peers disappear after ",[953,4069,4070],{},"staleMs"," (default 30 s) without an ",[953,4073,4074],{},"update()",". Call ",[953,4077,4074],{}," on a heartbeat if mere page-open should count as present.",[3343,4080,4081,4083,4084,4086,4087,4090,4091,999,4093,984,4095,4083,4097,4099,4100,1468],{},[953,4082,1105],{}," without ",[953,4085,962],{}," throws ",[953,4088,4089],{},"TeamNotEnabledError","; ",[953,4092,1090],{},[953,4094,1082],{},[953,4096,1086],{},[953,4098,959],{}," throw with a pointer at ",[953,4101,1077],{},[1021,4103,4105],{"id":4104},"see-also","See also",[3340,4107,4108,4114,4120,4126,4132,4137,4147,4157],{},[3343,4109,4110,4113],{},[1015,4111,653],{"href":4112},"..\u002Fservices\u002Fcrdt"," — the CRDT service page (modes, API reference)",[3343,4115,4116,4119],{},[1015,4117,864],{"href":4118},"..\u002Fservices\u002Fsync"," — replication, sync policies, conflict events",[3343,4121,4122,4125],{},[1015,4123,868],{"href":4124},"..\u002Fservices\u002Fteam"," — grants, roles, revocation, key rotation",[3343,4127,4128,4131],{},[1015,4129,840],{"href":4130},"..\u002Fservices\u002Fsession"," — session policies and timeouts",[3343,4133,4134,4136],{},[1015,4135,21],{"href":3337}," — the key hierarchy (KEK, keyring, DEK)",[3343,4138,4139,4146],{},[1015,4140,4143],{"href":4141,"rel":4142},"https:\u002F\u002Fgithub.com\u002Fnoy-db\u002Fdocs\u002Fblob\u002Fmain\u002Fshowcases\u002Fsrc\u002F14-with-crdt.showcase.test.ts",[1775],[953,4144,4145],{},"14-with-crdt.showcase.test.ts"," — runnable Yjs interop walkthrough",[3343,4148,4149,4156],{},[1015,4150,4153],{"href":4151,"rel":4152},"https:\u002F\u002Fgithub.com\u002Fnoy-db\u002Fdocs\u002Fblob\u002Fmain\u002Fshowcases\u002Fsrc\u002F15-with-sync.showcase.test.ts",[1775],[953,4154,4155],{},"15-with-sync.showcase.test.ts"," — runnable push\u002Fpull walkthrough",[3343,4158,4159,4161],{},[1015,4160,597],{"href":598}," — the full opt-in service catalog",[4163,4164,4165],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":1172,"searchDepth":1230,"depth":1230,"links":4167},[4168,4169,4170,4171,4172,4173,4174,4175,4176,4177],{"id":1023,"depth":1210,"text":1024},{"id":1158,"depth":1210,"text":1159},{"id":1766,"depth":1210,"text":1767},{"id":2222,"depth":1210,"text":2223},{"id":2718,"depth":1210,"text":2719},{"id":3036,"depth":1210,"text":3037},{"id":3369,"depth":1210,"text":3370},{"id":3730,"depth":1210,"text":3731},{"id":4046,"depth":1210,"text":4047},{"id":4104,"depth":1210,"text":4105},null,"Wire CRDT merge, cross-device push\u002Fpull replication, live presence, and multi-user grants onto an encrypted store so every device converges on the same result.","md",{},{"title":572,"description":4179},"stable","important","f5CaWwSbtfDfD-fgQGo2O7SpdPmE6icMJeGa03sAS_U",1791896576704]