[{"data":1,"prerenderedAt":1610},["ShallowReactive",2],{"navigation-landing-en":3,"navigation-nuxt-auto-en":180,"navigation-nuxt-protokit-en":365,"navigation-nuxt-cookie-consent-en":507,"\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fmulti-tenant-isolation-en":549,"\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fmulti-tenant-isolation-surround-en":1605},[4,8,13,28,41,51,64,77,94,110,134,150,157,172],{"title":5,"path":6,"stem":7},"Overview","\u002Fdocs\u002Flanding","0.docs\u002F1.landing\u002F001.index",{"title":9,"path":10,"stem":11,"badge":12},"Built-in Features","\u002Fdocs\u002Flanding\u002Fbuilt-in-features","0.docs\u002F1.landing\u002F002.built-in-features","New",{"title":14,"path":15,"stem":16,"children":17,"icon":27},"Content Foundation","\u002Fdocs\u002Flanding\u002Fcontent","0.docs\u002F1.landing\u002F02.content\u002F1.index",[18,19,23],{"title":5,"path":15,"stem":16},{"title":20,"path":21,"stem":22},"Details","\u002Fdocs\u002Flanding\u002Fcontent\u002Fdetails","0.docs\u002F1.landing\u002F02.content\u002F2.details",{"title":24,"path":25,"stem":26},"Technical","\u002Fdocs\u002Flanding\u002Fcontent\u002Ftechnical","0.docs\u002F1.landing\u002F02.content\u002F4.technical","i-heroicons-document-text",{"title":29,"path":30,"stem":31,"children":32,"icon":40},"Regional Content","\u002Fdocs\u002Flanding\u002Fregional","0.docs\u002F1.landing\u002F03.regional\u002F1.index",[33,34,37],{"title":5,"path":30,"stem":31},{"title":20,"path":35,"stem":36},"\u002Fdocs\u002Flanding\u002Fregional\u002Fdetails","0.docs\u002F1.landing\u002F03.regional\u002F2.details",{"title":24,"path":38,"stem":39},"\u002Fdocs\u002Flanding\u002Fregional\u002Ftechnical","0.docs\u002F1.landing\u002F03.regional\u002F4.technical","i-heroicons-globe-alt",{"title":42,"path":43,"stem":44,"children":45,"icon":50},"Multi-language","\u002Fdocs\u002Flanding\u002Fmultilang","0.docs\u002F1.landing\u002F04.multilang\u002F1.index",[46,47],{"title":5,"path":43,"stem":44},{"title":20,"path":48,"stem":49},"\u002Fdocs\u002Flanding\u002Fmultilang\u002Fdetails","0.docs\u002F1.landing\u002F04.multilang\u002F2.details","i-heroicons-language",{"title":52,"path":53,"stem":54,"children":55,"icon":63},"Blog","\u002Fdocs\u002Flanding\u002Fblog","0.docs\u002F1.landing\u002F05.blog\u002F1.index",[56,57,60],{"title":5,"path":53,"stem":54},{"title":20,"path":58,"stem":59},"\u002Fdocs\u002Flanding\u002Fblog\u002Fdetails","0.docs\u002F1.landing\u002F05.blog\u002F2.details",{"title":24,"path":61,"stem":62},"\u002Fdocs\u002Flanding\u002Fblog\u002Ftechnical","0.docs\u002F1.landing\u002F05.blog\u002F4.technical","i-heroicons-pencil-square",{"title":65,"path":66,"stem":67,"children":68,"icon":76},"Documentation","\u002Fdocs\u002Flanding\u002Fdocs","0.docs\u002F1.landing\u002F06.docs\u002F1.index",[69,70,73],{"title":5,"path":66,"stem":67},{"title":20,"path":71,"stem":72},"\u002Fdocs\u002Flanding\u002Fdocs\u002Fdetails","0.docs\u002F1.landing\u002F06.docs\u002F2.details",{"title":24,"path":74,"stem":75},"\u002Fdocs\u002Flanding\u002Fdocs\u002Ftechnical","0.docs\u002F1.landing\u002F06.docs\u002F4.technical","i-heroicons-book-open",{"title":78,"path":79,"stem":80,"children":81,"icon":93},"Forms","\u002Fdocs\u002Flanding\u002Fforms","0.docs\u002F1.landing\u002F07.forms\u002F1.index",[82,83,86,90],{"title":5,"path":79,"stem":80},{"title":20,"path":84,"stem":85},"\u002Fdocs\u002Flanding\u002Fforms\u002Fdetails","0.docs\u002F1.landing\u002F07.forms\u002F2.details",{"title":87,"path":88,"stem":89},"Admin","\u002Fdocs\u002Flanding\u002Fforms\u002Fadmin","0.docs\u002F1.landing\u002F07.forms\u002F3.admin",{"title":24,"path":91,"stem":92},"\u002Fdocs\u002Flanding\u002Fforms\u002Ftechnical","0.docs\u002F1.landing\u002F07.forms\u002F4.technical","i-heroicons-clipboard-document-list",{"title":95,"path":96,"stem":97,"children":98,"icon":109},"Email","\u002Fdocs\u002Flanding\u002Femail","0.docs\u002F1.landing\u002F08.email\u002F1.index",[99,100,103,106],{"title":5,"path":96,"stem":97},{"title":20,"path":101,"stem":102},"\u002Fdocs\u002Flanding\u002Femail\u002Fdetails","0.docs\u002F1.landing\u002F08.email\u002F2.details",{"title":87,"path":104,"stem":105},"\u002Fdocs\u002Flanding\u002Femail\u002Fadmin","0.docs\u002F1.landing\u002F08.email\u002F3.admin",{"title":24,"path":107,"stem":108},"\u002Fdocs\u002Flanding\u002Femail\u002Ftechnical","0.docs\u002F1.landing\u002F08.email\u002F4.technical","i-heroicons-envelope",{"title":111,"path":112,"stem":113,"children":114,"icon":133},"Feedback Platform","\u002Fdocs\u002Flanding\u002Ffeedback","0.docs\u002F1.landing\u002F09.feedback\u002F1.index",[115,116,119,122,125,129],{"title":5,"path":112,"stem":113},{"title":20,"path":117,"stem":118},"\u002Fdocs\u002Flanding\u002Ffeedback\u002Fdetails","0.docs\u002F1.landing\u002F09.feedback\u002F2.details",{"title":87,"path":120,"stem":121},"\u002Fdocs\u002Flanding\u002Ffeedback\u002Fadmin","0.docs\u002F1.landing\u002F09.feedback\u002F3.admin",{"title":24,"path":123,"stem":124},"\u002Fdocs\u002Flanding\u002Ffeedback\u002Ftechnical","0.docs\u002F1.landing\u002F09.feedback\u002F4.technical",{"title":126,"path":127,"stem":128},"Compare vs SaaS","\u002Fdocs\u002Flanding\u002Ffeedback\u002Fcompare","0.docs\u002F1.landing\u002F09.feedback\u002F5.compare",{"title":130,"path":131,"stem":132},"FAQ","\u002Fdocs\u002Flanding\u002Ffeedback\u002Ffaq","0.docs\u002F1.landing\u002F09.feedback\u002F6.faq","i-heroicons-chat-bubble-left-right",{"title":135,"path":136,"stem":137,"children":138,"icon":149},"Storage","\u002Fdocs\u002Flanding\u002Fstorage","0.docs\u002F1.landing\u002F10.storage\u002F1.index",[139,140,143,146],{"title":5,"path":136,"stem":137},{"title":20,"path":141,"stem":142},"\u002Fdocs\u002Flanding\u002Fstorage\u002Fdetails","0.docs\u002F1.landing\u002F10.storage\u002F2.details",{"title":87,"path":144,"stem":145},"\u002Fdocs\u002Flanding\u002Fstorage\u002Fadmin","0.docs\u002F1.landing\u002F10.storage\u002F3.admin",{"title":24,"path":147,"stem":148},"\u002Fdocs\u002Flanding\u002Fstorage\u002Ftechnical","0.docs\u002F1.landing\u002F10.storage\u002F4.technical","i-heroicons-circle-stack",{"title":151,"path":152,"stem":153,"children":154,"icon":156},"Offline First","\u002Fdocs\u002Flanding\u002Foffline-first","0.docs\u002F1.landing\u002F11.offline-first\u002F1.index",[155],{"title":151,"path":152,"stem":153},"i-heroicons-users",{"title":158,"path":159,"stem":160,"children":161,"icon":156},"Yjs Sync","\u002Fdocs\u002Flanding\u002Fyjs-sync","0.docs\u002F1.landing\u002F12.yjs-sync\u002F1.index",[162,163,166,169],{"title":5,"path":159,"stem":160},{"title":20,"path":164,"stem":165},"\u002Fdocs\u002Flanding\u002Fyjs-sync\u002Fdetails","0.docs\u002F1.landing\u002F12.yjs-sync\u002F2.details",{"title":87,"path":167,"stem":168},"\u002Fdocs\u002Flanding\u002Fyjs-sync\u002Fadmin","0.docs\u002F1.landing\u002F12.yjs-sync\u002F3.admin",{"title":24,"path":170,"stem":171},"\u002Fdocs\u002Flanding\u002Fyjs-sync\u002Ftechnical","0.docs\u002F1.landing\u002F12.yjs-sync\u002F4.technical",{"title":173,"path":174,"stem":175,"children":176,"badge":178,"icon":179},"Newsletter","\u002Fdocs\u002Flanding\u002Fnewsletter","0.docs\u002F1.landing\u002F13.newsletter\u002Findex",[177],{"title":173,"path":174,"stem":175,"badge":178},"Coming Soon","i-lucide-send",[181,184,202,318,358],{"title":5,"path":182,"stem":183},"\u002Fdocs\u002Fnuxt-auto","0.docs\u002F3.nuxt-auto\u002Findex",{"title":185,"path":186,"stem":187,"children":188,"page":201},"Getting Started","\u002Fdocs\u002Fnuxt-auto\u002Fgetting-started","0.docs\u002F3.nuxt-auto\u002F1.getting-started",[189,193,197],{"title":190,"path":191,"stem":192},"Introduction","\u002Fdocs\u002Fnuxt-auto\u002Fgetting-started\u002Fintroduction","0.docs\u002F3.nuxt-auto\u002F1.getting-started\u002F1.introduction",{"title":194,"path":195,"stem":196},"Installation","\u002Fdocs\u002Fnuxt-auto\u002Fgetting-started\u002Finstallation","0.docs\u002F3.nuxt-auto\u002F1.getting-started\u002F2.installation",{"title":198,"path":199,"stem":200},"Quick Start","\u002Fdocs\u002Fnuxt-auto\u002Fgetting-started\u002Fquick-start","0.docs\u002F3.nuxt-auto\u002F1.getting-started\u002F3.quick-start",false,{"title":203,"path":204,"stem":205,"children":206,"page":201},"Auto API","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api","0.docs\u002F3.nuxt-auto\u002F2.auto-api",[207,210,214,218,222,226,230,234,238,242,246,250,254,258,262,266,270,274,278,282,286,290,294,298,302,306,310,314],{"title":185,"path":208,"stem":209},"\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fgetting-started","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F1.getting-started",{"title":211,"path":212,"stem":213},"Aggregations","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Faggregations","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F10.aggregations",{"title":215,"path":216,"stem":217},"Lifecycle Hooks","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Flifecycle-hooks","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F11.lifecycle-hooks",{"title":219,"path":220,"stem":221},"Many-to-Many (M2M) Relationships","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fm2m-relationships","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F12.m2m-relationships",{"title":223,"path":224,"stem":225},"Plugin System","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fplugin-system","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F13.plugin-system",{"title":227,"path":228,"stem":229},"Database Adapters","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fdatabase-adapters","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F14.database-adapters",{"title":231,"path":232,"stem":233},"Custom Endpoints","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fcustom-endpoints","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F15.custom-endpoints",{"title":235,"path":236,"stem":237},"Multi-Tenancy","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fmulti-tenancy","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F16.multi-tenancy",{"title":239,"path":240,"stem":241},"Schema Presets (Cross-engine)","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fschema-presets","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F17.schema-presets",{"title":243,"path":244,"stem":245},"Permissions Cookbook","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fpermissions-cookbook","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F18.permissions-cookbook",{"title":247,"path":248,"stem":249},"Billing & Plan Gating","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fbilling","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F19.billing",{"title":251,"path":252,"stem":253},"Validation","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fvalidation","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F2.validation",{"title":255,"path":256,"stem":257},"Rate Limiting","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Frate-limiting","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F20.rate-limiting",{"title":259,"path":260,"stem":261},"Request Metadata Plugin","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Frequest-metadata","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F21.request-metadata",{"title":263,"path":264,"stem":265},"Plugin Catalog","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fplugin-catalog","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F22.plugin-catalog",{"title":267,"path":268,"stem":269},"Configuration Reference","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fconfiguration","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F23.configuration",{"title":271,"path":272,"stem":273},"Handler Overrides","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fhandler-overrides","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F3.handler-overrides",{"title":275,"path":276,"stem":277},"Cloudflare D1","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fcloudflare-d1","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F30.cloudflare-d1",{"title":279,"path":280,"stem":281},"SQLite to D1 Migration","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fmigration-sqlite-d1","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F31.migration-sqlite-d1",{"title":283,"path":284,"stem":285},"Frontend Composables","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Ffrontend-composables","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F32.frontend-composables",{"title":287,"path":288,"stem":289},"Testing","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Ftesting","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F33.testing",{"title":291,"path":292,"stem":293},"Pagination","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fpagination","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F4.pagination",{"title":295,"path":296,"stem":297},"Upgrading","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fupgrading","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F40.upgrading",{"title":299,"path":300,"stem":301},"Soft Deletes","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fsoft-deletes","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F5.soft-deletes",{"title":303,"path":304,"stem":305},"Authentication & Authorization","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fauthentication-authorization","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F6.authentication-authorization",{"title":307,"path":308,"stem":309},"Better-Auth Integration","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fbetter-auth","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F7.better-auth",{"title":311,"path":312,"stem":313},"Nested Relations","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fnested-relationships","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F8.nested-relationships",{"title":315,"path":316,"stem":317},"Bulk Operations","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fbulk-operations","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F9.bulk-operations",{"title":319,"path":320,"stem":321,"children":322,"page":201},"Auto Admin","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin","0.docs\u002F3.nuxt-auto\u002F3.auto-admin",[323,326,330,334,338,342,346,350,354],{"title":185,"path":324,"stem":325},"\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fgetting-started","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F1.getting-started",{"title":327,"path":328,"stem":329},"Configuration & Theming","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fconfiguration-theming","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F2.configuration-theming",{"title":331,"path":332,"stem":333},"Resource Configuration","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fresource-configuration","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F3.resource-configuration",{"title":335,"path":336,"stem":337},"Form Fields & Widgets","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fform-fields-widgets","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F4.form-fields-widgets",{"title":339,"path":340,"stem":341},"Permissions","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fpermissions","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F5.permissions",{"title":343,"path":344,"stem":345},"Custom Pages","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fcustom-pages","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F6.custom-pages",{"title":347,"path":348,"stem":349},"M2M Relationships","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fm2m-relationships","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F7.m2m-relationships",{"title":351,"path":352,"stem":353},"Custom Actions","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fcustom-actions","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F8.custom-actions",{"title":355,"path":356,"stem":357},"Composables","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fcomposables","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F9.composables",{"title":359,"path":360,"stem":361,"children":362,"icon":364},"Claude Code Skills","\u002Fdocs\u002Fnuxt-auto\u002Fclaude-code-skills","0.docs\u002F3.nuxt-auto\u002F4.claude-code-skills\u002F1.index",[363],{"title":5,"path":360,"stem":361},"i-lucide-bot",[366,369,382,409,427,450,472,502],{"title":5,"path":367,"stem":368},"\u002Fdocs\u002Fnuxt-protokit","0.docs\u002F4.nuxt-protokit\u002Findex",{"title":185,"path":370,"stem":371,"children":372,"icon":381},"\u002Fdocs\u002Fnuxt-protokit\u002Fgetting-started","0.docs\u002F4.nuxt-protokit\u002F1.getting-started\u002F1.index",[373,374,378],{"title":190,"path":370,"stem":371},{"title":375,"path":376,"stem":377},"Core Concepts","\u002Fdocs\u002Fnuxt-protokit\u002Fgetting-started\u002Fconcepts","0.docs\u002F4.nuxt-protokit\u002F1.getting-started\u002F2.concepts",{"title":198,"path":379,"stem":380},"\u002Fdocs\u002Fnuxt-protokit\u002Fgetting-started\u002Fquick-start","0.docs\u002F4.nuxt-protokit\u002F1.getting-started\u002F3.quick-start","i-lucide-rocket",{"title":383,"path":384,"stem":385,"children":386,"icon":408},"Schemas","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F1.index",[387,388,392,396,400,404],{"title":5,"path":384,"stem":385},{"title":389,"path":390,"stem":391},"Field Types","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Ffields","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F2.fields",{"title":393,"path":394,"stem":395},"Collections","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Fcollections","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F3.collections",{"title":397,"path":398,"stem":399},"Derived & Computed","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Fderived-computed","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F4.derived-computed",{"title":401,"path":402,"stem":403},"Connections","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Fconnections","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F5.connections",{"title":405,"path":406,"stem":407},"Visualizations & Layouts","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Fvisualizations","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F6.visualizations","i-lucide-file-code",{"title":355,"path":410,"stem":411,"children":412,"icon":426},"\u002Fdocs\u002Fnuxt-protokit\u002Fcomposables","0.docs\u002F4.nuxt-protokit\u002F3.composables\u002F1.index",[413,414,418,422],{"title":5,"path":410,"stem":411},{"title":415,"path":416,"stem":417},"usePrototype","\u002Fdocs\u002Fnuxt-protokit\u002Fcomposables\u002Fuse-prototype","0.docs\u002F4.nuxt-protokit\u002F3.composables\u002F2.use-prototype",{"title":419,"path":420,"stem":421},"useProtoDoc","\u002Fdocs\u002Fnuxt-protokit\u002Fcomposables\u002Fuse-proto-doc","0.docs\u002F4.nuxt-protokit\u002F3.composables\u002F3.use-proto-doc",{"title":423,"path":424,"stem":425},"useProtoCollection","\u002Fdocs\u002Fnuxt-protokit\u002Fcomposables\u002Fuse-proto-collection","0.docs\u002F4.nuxt-protokit\u002F3.composables\u002F4.use-proto-collection","i-lucide-layers",{"title":428,"path":429,"stem":430,"children":431,"icon":449},"Components","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F1.index",[432,433,437,441,445],{"title":5,"path":429,"stem":430},{"title":434,"path":435,"stem":436},"ProtoTool","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents\u002Fproto-tool","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F2.proto-tool",{"title":438,"path":439,"stem":440},"ProtoCrudModal","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents\u002Fproto-crud-modal","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F3.proto-crud-modal",{"title":442,"path":443,"stem":444},"ProtoCalendar","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents\u002Fproto-calendar","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F4.proto-calendar",{"title":446,"path":447,"stem":448},"ProtoItemPanel variants","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents\u002Fproto-item-panels","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F5.proto-item-panels","i-lucide-puzzle",{"title":151,"path":451,"stem":452,"children":453,"icon":471},"\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F1.index",[454,455,459,463,467],{"title":151,"path":451,"stem":452},{"title":456,"path":457,"stem":458},"Corruption Recovery","\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fcorruption-recovery","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F2.corruption-recovery",{"title":460,"path":461,"stem":462},"Size & GC","\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fdocument-size-and-gc","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F3.document-size-and-gc",{"title":464,"path":465,"stem":466},"Multi-tenant Isolation","\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fmulti-tenant-isolation","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F4.multi-tenant-isolation",{"title":468,"path":469,"stem":470},"Encryption at Rest","\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fencryption","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F5.encryption","i-lucide-wifi-off",{"title":473,"icon":474,"path":475,"stem":476,"children":477},"Advanced","i-lucide-graduation-cap","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F1.index",[478,479,483,487,491,494,498],{"title":5,"path":475,"stem":476},{"title":480,"path":481,"stem":482},"Multi-Tool Apps","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fbuilding-a-toolkit","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F1.building-a-toolkit",{"title":484,"path":485,"stem":486},"Schema Patterns","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fcustom-schema-patterns","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F2.custom-schema-patterns",{"title":488,"path":489,"stem":490},"Custom Fields & Viz","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fextensibility","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F3.extensibility",{"title":339,"path":492,"stem":493},"\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fpermissions","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F4.permissions",{"title":495,"path":496,"stem":497},"Business Logic Guards","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fpermissions-business-logic","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F5.permissions-business-logic",{"title":499,"path":500,"stem":501},"Headless Mode","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fheadless-mode","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F6.headless-mode",{"title":359,"path":503,"stem":504,"children":505,"icon":364},"\u002Fdocs\u002Fnuxt-protokit\u002Fclaude-code-skills","0.docs\u002F4.nuxt-protokit\u002F7.claude-code-skills\u002F1.index",[506],{"title":5,"path":503,"stem":504},[508,511],{"title":5,"path":509,"stem":510},"\u002Fdocs\u002Fnuxt-cookie-consent","0.docs\u002F5.nuxt-cookie-consent\u002Findex",{"title":512,"icon":513,"path":514,"stem":515,"children":516,"page":201},"Guide","i-lucide-book-open","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide",[517,521,525,530,535,539,544],{"title":190,"path":518,"stem":519,"icon":520},"\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fintroduction","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F1.introduction","i-lucide-info",{"title":194,"path":522,"stem":523,"icon":524},"\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Finstallation","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F2.installation","i-lucide-download",{"title":526,"path":527,"stem":528,"icon":529},"Configuration","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fconfiguration","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F3.configuration","i-lucide-settings-2",{"title":531,"path":532,"stem":533,"icon":534},"Usage","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fusage","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F4.usage","i-lucide-play",{"title":355,"path":536,"stem":537,"icon":538},"\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fcomposables","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F5.composables","i-lucide-function-square",{"title":540,"path":541,"stem":542,"icon":543},"Components & overriding","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fcomponents","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F6.components","i-lucide-component",{"title":545,"path":546,"stem":547,"icon":548},"Internationalization","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fi18n","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F7.i18n","i-lucide-languages",{"page":550,"fallbackPage":1600},{"id":551,"title":552,"body":553,"description":1598,"extension":1599,"links":1600,"meta":1601,"navigation":1602,"ogImage":1600,"path":465,"seo":1603,"stem":466,"__hash__":1604},"nuxt_protokit\u002F0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F4.multi-tenant-isolation.md","Multi-tenant & Per-user Isolation",{"type":554,"value":555,"toc":1585},"minimark",[556,560,569,576,585,598,608,611,781,842,845,860,864,872,877,890,895,906,910,913,921,924,1069,1083,1090,1093,1205,1212,1323,1327,1330,1533,1537,1540,1578,1581],[557,558,552],"h1",{"id":559},"multi-tenant-per-user-isolation",[561,562,563,564,568],"p",{},"By default every prototype stores data under ",[565,566,567],"code",{},"proto:\u003Cschema.key>"," — a single shared document per device. In apps with authentication or multi-tenancy, you need isolated documents per user, tenant, or workspace so one account's data never surfaces to another.",[561,570,571],{},[572,573],"img",{"alt":574,"src":575},"Alice signed in: her own document under the namespace tenant_acme:usr_alice","\u002Fscreenshots\u002Fnuxt-protokit\u002Fnamespace-isolation-1440.png",[577,578,580,581,584],"h2",{"id":579},"the-namespace-option","The ",[565,582,583],{},"namespace"," option",[561,586,587,588,590,591,593,594,597],{},"Pass a ",[565,589,583],{}," string to ",[565,592,415],{}," or the ",[565,595,596],{},"\u003CProtoTool>"," component. It is prepended to the doc key, creating fully isolated IndexedDB stores and BroadcastChannels.",[599,600,605],"pre",{"className":601,"code":603,"language":604},[602],"language-text","IndexedDB key: proto:\u003Cnamespace>:\u003Cschema.key>\n","text",[565,606,603],{"__ignoreMap":607},"",[561,609,610],{},"You compose the namespace from whatever segments your app requires:",[599,612,616],{"className":613,"code":614,"language":615,"meta":607,"style":607},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Tenant-shared: all users in the org read and write the same document\nconst { state } = usePrototype(mySchema, { namespace: tenantId })\n\n\u002F\u002F Private per user within a tenant\nconst { state } = usePrototype(mySchema, { namespace: `${tenantId}:${userId}` })\n\n\u002F\u002F Private per user, single-tenant \u002F no multi-tenancy\nconst { state } = usePrototype(mySchema, { namespace: userId })\n","typescript",[565,617,618,627,675,682,688,738,743,749],{"__ignoreMap":607},[619,620,623],"span",{"class":621,"line":622},"line",1,[619,624,626],{"class":625},"sHwdD","\u002F\u002F Tenant-shared: all users in the org read and write the same document\n",[619,628,630,634,638,642,645,648,652,655,658,660,664,667,670,672],{"class":621,"line":629},2,[619,631,633],{"class":632},"spNyl","const",[619,635,637],{"class":636},"sMK4o"," {",[619,639,641],{"class":640},"sTEyZ"," state ",[619,643,644],{"class":636},"}",[619,646,647],{"class":636}," =",[619,649,651],{"class":650},"s2Zo4"," usePrototype",[619,653,654],{"class":640},"(mySchema",[619,656,657],{"class":636},",",[619,659,637],{"class":636},[619,661,663],{"class":662},"swJcz"," namespace",[619,665,666],{"class":636},":",[619,668,669],{"class":640}," tenantId ",[619,671,644],{"class":636},[619,673,674],{"class":640},")\n",[619,676,678],{"class":621,"line":677},3,[619,679,681],{"emptyLinePlaceholder":680},true,"\n",[619,683,685],{"class":621,"line":684},4,[619,686,687],{"class":625},"\u002F\u002F Private per user within a tenant\n",[619,689,691,693,695,697,699,701,703,705,707,709,711,713,716,719,721,724,727,730,733,736],{"class":621,"line":690},5,[619,692,633],{"class":632},[619,694,637],{"class":636},[619,696,641],{"class":640},[619,698,644],{"class":636},[619,700,647],{"class":636},[619,702,651],{"class":650},[619,704,654],{"class":640},[619,706,657],{"class":636},[619,708,637],{"class":636},[619,710,663],{"class":662},[619,712,666],{"class":636},[619,714,715],{"class":636}," `${",[619,717,718],{"class":640},"tenantId",[619,720,644],{"class":636},[619,722,666],{"class":723},"sfazB",[619,725,726],{"class":636},"${",[619,728,729],{"class":640},"userId",[619,731,732],{"class":636},"}`",[619,734,735],{"class":636}," }",[619,737,674],{"class":640},[619,739,741],{"class":621,"line":740},6,[619,742,681],{"emptyLinePlaceholder":680},[619,744,746],{"class":621,"line":745},7,[619,747,748],{"class":625},"\u002F\u002F Private per user, single-tenant \u002F no multi-tenancy\n",[619,750,752,754,756,758,760,762,764,766,768,770,772,774,777,779],{"class":621,"line":751},8,[619,753,633],{"class":632},[619,755,637],{"class":636},[619,757,641],{"class":640},[619,759,644],{"class":636},[619,761,647],{"class":636},[619,763,651],{"class":650},[619,765,654],{"class":640},[619,767,657],{"class":636},[619,769,637],{"class":636},[619,771,663],{"class":662},[619,773,666],{"class":636},[619,775,776],{"class":640}," userId ",[619,778,644],{"class":636},[619,780,674],{"class":640},[599,782,786],{"className":783,"code":784,"language":785,"meta":607,"style":607},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- Component usage -->\n\u003CProtoTool :schema=\"mySchema\" :namespace=\"`${tenantId}:${userId}`\" \u002F>\n","vue",[565,787,788,793],{"__ignoreMap":607},[619,789,790],{"class":621,"line":622},[619,791,792],{"class":625},"\u003C!-- Component usage -->\n",[619,794,795,798,800,803,806,809,812,815,817,819,821,823,826,828,830,832,834,836,839],{"class":621,"line":629},[619,796,797],{"class":636},"\u003C",[619,799,434],{"class":662},[619,801,802],{"class":636}," :",[619,804,805],{"class":632},"schema",[619,807,808],{"class":636},"=",[619,810,811],{"class":636},"\"",[619,813,814],{"class":640},"mySchema",[619,816,811],{"class":636},[619,818,802],{"class":636},[619,820,583],{"class":632},[619,822,808],{"class":636},[619,824,825],{"class":636},"\"`${",[619,827,718],{"class":640},[619,829,644],{"class":636},[619,831,666],{"class":723},[619,833,726],{"class":636},[619,835,729],{"class":640},[619,837,838],{"class":636},"}`\"",[619,840,841],{"class":636}," \u002F>\n",[561,843,844],{},"When the namespace changes (user switches tenant, logs out, logs in as someone else), the component or composable receives a different key and opens a completely different document. No data bleeds across namespaces.",[846,847,849],"callout",{"color":848,"icon":520},"blue",[561,850,851,852,855,856,859],{},"When ",[565,853,854],{},"serverSync"," is enabled, the same namespaced key is sent to the server as the ",[565,857,858],{},"docKey",". The backend stores each namespace separately, so server-side isolation matches client-side isolation automatically.",[577,861,863],{"id":862},"security-concern-data-at-rest-after-logout","Security concern: data at rest after logout",[561,865,866,867,871],{},"IndexedDB data persists on the device after a user logs out. A subsequent user on the same device cannot access it through normal app usage — the namespace ensures they open a different, empty document. However, on a ",[868,869,870],"strong",{},"shared or public device",", a technically capable person could inspect the previous user's IndexedDB store directly via DevTools or a browser extension, without logging in.",[561,873,874],{},[868,875,876],{},"When this is acceptable:",[878,879,880,884,887],"ul",{},[881,882,883],"li",{},"Internal tools where employees each use their own device",[881,885,886],{},"Single-user apps or MVPs",[881,888,889],{},"Tools handling non-sensitive data (calculator inputs, estimates, planning worksheets)",[561,891,892],{},[868,893,894],{},"When you should clean up on logout:",[878,896,897,900,903],{},[881,898,899],{},"Apps on shared\u002Fkiosk devices",[881,901,902],{},"Handling PII, financial data, medical records, or other regulated data",[881,904,905],{},"Any scenario where GDPR or similar regulations require data erasure on request",[577,907,909],{"id":908},"cleanup-on-logout","Cleanup on logout",[561,911,912],{},"Two utilities are exported for this. Call either one in your logout handler before clearing the session.",[914,915,917,920],"h3",{"id":916},"clearprotonamespacenamespace-recommended-for-most-apps",[565,918,919],{},"clearProtoNamespace(namespace)"," — recommended for most apps",[561,922,923],{},"Auto-discovers and deletes all IndexedDB stores for the namespace, including stores from previous sessions.",[599,925,927],{"className":613,"code":926,"language":615,"meta":607,"style":607},"async function logout() {\n  const { tenantId, userId } = useCurrentUser()\n\n  await clearProtoNamespace(`${tenantId}:${userId}`)\n\n  await $fetch('\u002Fapi\u002Fauth\u002Flogout', { method: 'POST' })\n  await navigateTo('\u002Flogin')\n}\n",[565,928,929,946,971,975,1004,1008,1046,1064],{"__ignoreMap":607},[619,930,931,934,937,940,943],{"class":621,"line":622},[619,932,933],{"class":632},"async",[619,935,936],{"class":632}," function",[619,938,939],{"class":650}," logout",[619,941,942],{"class":636},"()",[619,944,945],{"class":636}," {\n",[619,947,948,951,953,956,958,961,963,965,968],{"class":621,"line":629},[619,949,950],{"class":632},"  const",[619,952,637],{"class":636},[619,954,955],{"class":640}," tenantId",[619,957,657],{"class":636},[619,959,960],{"class":640}," userId",[619,962,735],{"class":636},[619,964,647],{"class":636},[619,966,967],{"class":650}," useCurrentUser",[619,969,970],{"class":662},"()\n",[619,972,973],{"class":621,"line":677},[619,974,681],{"emptyLinePlaceholder":680},[619,976,977,981,984,987,990,992,994,996,998,1000,1002],{"class":621,"line":684},[619,978,980],{"class":979},"s7zQu","  await",[619,982,983],{"class":650}," clearProtoNamespace",[619,985,986],{"class":662},"(",[619,988,989],{"class":636},"`${",[619,991,718],{"class":640},[619,993,644],{"class":636},[619,995,666],{"class":723},[619,997,726],{"class":636},[619,999,729],{"class":640},[619,1001,732],{"class":636},[619,1003,674],{"class":662},[619,1005,1006],{"class":621,"line":690},[619,1007,681],{"emptyLinePlaceholder":680},[619,1009,1010,1012,1015,1017,1020,1023,1025,1027,1029,1032,1034,1037,1040,1042,1044],{"class":621,"line":740},[619,1011,980],{"class":979},[619,1013,1014],{"class":650}," $fetch",[619,1016,986],{"class":662},[619,1018,1019],{"class":636},"'",[619,1021,1022],{"class":723},"\u002Fapi\u002Fauth\u002Flogout",[619,1024,1019],{"class":636},[619,1026,657],{"class":636},[619,1028,637],{"class":636},[619,1030,1031],{"class":662}," method",[619,1033,666],{"class":636},[619,1035,1036],{"class":636}," '",[619,1038,1039],{"class":723},"POST",[619,1041,1019],{"class":636},[619,1043,735],{"class":636},[619,1045,674],{"class":662},[619,1047,1048,1050,1053,1055,1057,1060,1062],{"class":621,"line":745},[619,1049,980],{"class":979},[619,1051,1052],{"class":650}," navigateTo",[619,1054,986],{"class":662},[619,1056,1019],{"class":636},[619,1058,1059],{"class":723},"\u002Flogin",[619,1061,1019],{"class":636},[619,1063,674],{"class":662},[619,1065,1066],{"class":621,"line":751},[619,1067,1068],{"class":636},"}\n",[561,1070,1071,1074,1075,1078,1079,1082],{},[868,1072,1073],{},"Browser support:"," uses ",[565,1076,1077],{},"indexedDB.databases()",", which is available in Chromium and Safari. On Firefox, only stores currently open in memory are cleaned up — stores from previous page loads remain on disk. If full Firefox support matters, use ",[565,1080,1081],{},"clearProtoKeys"," instead.",[914,1084,1086,1089],{"id":1085},"clearprotokeysnamespace-schemakeys-cross-browser",[565,1087,1088],{},"clearProtoKeys(namespace, schemaKeys)"," — cross-browser",[561,1091,1092],{},"Enumerate the schema keys explicitly. Works in all browsers including Firefox, because keys are deterministic.",[599,1094,1096],{"className":613,"code":1095,"language":615,"meta":607,"style":607},"import { budgetSchema, interviewSchema, roadmapSchema } from '~\u002Fschemas'\n\nawait clearProtoKeys(`${tenantId}:${userId}`, [\n  budgetSchema.key,\n  interviewSchema.key,\n  roadmapSchema.key,\n])\n",[565,1097,1098,1131,1135,1164,1178,1189,1200],{"__ignoreMap":607},[619,1099,1100,1103,1105,1108,1110,1113,1115,1118,1120,1123,1125,1128],{"class":621,"line":622},[619,1101,1102],{"class":979},"import",[619,1104,637],{"class":636},[619,1106,1107],{"class":640}," budgetSchema",[619,1109,657],{"class":636},[619,1111,1112],{"class":640}," interviewSchema",[619,1114,657],{"class":636},[619,1116,1117],{"class":640}," roadmapSchema",[619,1119,735],{"class":636},[619,1121,1122],{"class":979}," from",[619,1124,1036],{"class":636},[619,1126,1127],{"class":723},"~\u002Fschemas",[619,1129,1130],{"class":636},"'\n",[619,1132,1133],{"class":621,"line":629},[619,1134,681],{"emptyLinePlaceholder":680},[619,1136,1137,1140,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161],{"class":621,"line":677},[619,1138,1139],{"class":979},"await",[619,1141,1142],{"class":650}," clearProtoKeys",[619,1144,986],{"class":640},[619,1146,989],{"class":636},[619,1148,718],{"class":640},[619,1150,644],{"class":636},[619,1152,666],{"class":723},[619,1154,726],{"class":636},[619,1156,729],{"class":640},[619,1158,732],{"class":636},[619,1160,657],{"class":636},[619,1162,1163],{"class":640}," [\n",[619,1165,1166,1169,1172,1175],{"class":621,"line":684},[619,1167,1168],{"class":640},"  budgetSchema",[619,1170,1171],{"class":636},".",[619,1173,1174],{"class":640},"key",[619,1176,1177],{"class":636},",\n",[619,1179,1180,1183,1185,1187],{"class":621,"line":690},[619,1181,1182],{"class":640},"  interviewSchema",[619,1184,1171],{"class":636},[619,1186,1174],{"class":640},[619,1188,1177],{"class":636},[619,1190,1191,1194,1196,1198],{"class":621,"line":740},[619,1192,1193],{"class":640},"  roadmapSchema",[619,1195,1171],{"class":636},[619,1197,1174],{"class":640},[619,1199,1177],{"class":636},[619,1201,1202],{"class":621,"line":745},[619,1203,1204],{"class":640},"])\n",[561,1206,1207,1208,1211],{},"This requires keeping the list in sync with your schemas. A practical pattern is to export all schemas from a single ",[565,1209,1210],{},"~\u002Fschemas\u002Findex.ts"," and derive the key list from it:",[599,1213,1215],{"className":613,"code":1214,"language":615,"meta":607,"style":607},"\u002F\u002F schemas\u002Findex.ts\nexport const allSchemas = [budgetSchema, interviewSchema, roadmapSchema]\n\n\u002F\u002F logout handler\nimport { allSchemas } from '~\u002Fschemas'\nawait clearProtoKeys(`${tenantId}:${userId}`, allSchemas.map(s => s.key))\n",[565,1216,1217,1222,1247,1251,1256,1275],{"__ignoreMap":607},[619,1218,1219],{"class":621,"line":622},[619,1220,1221],{"class":625},"\u002F\u002F schemas\u002Findex.ts\n",[619,1223,1224,1227,1230,1233,1235,1238,1240,1242,1244],{"class":621,"line":629},[619,1225,1226],{"class":979},"export",[619,1228,1229],{"class":632}," const",[619,1231,1232],{"class":640}," allSchemas ",[619,1234,808],{"class":636},[619,1236,1237],{"class":640}," [budgetSchema",[619,1239,657],{"class":636},[619,1241,1112],{"class":640},[619,1243,657],{"class":636},[619,1245,1246],{"class":640}," roadmapSchema]\n",[619,1248,1249],{"class":621,"line":677},[619,1250,681],{"emptyLinePlaceholder":680},[619,1252,1253],{"class":621,"line":684},[619,1254,1255],{"class":625},"\u002F\u002F logout handler\n",[619,1257,1258,1260,1262,1265,1267,1269,1271,1273],{"class":621,"line":690},[619,1259,1102],{"class":979},[619,1261,637],{"class":636},[619,1263,1264],{"class":640}," allSchemas",[619,1266,735],{"class":636},[619,1268,1122],{"class":979},[619,1270,1036],{"class":636},[619,1272,1127],{"class":723},[619,1274,1130],{"class":636},[619,1276,1277,1279,1281,1283,1285,1287,1289,1291,1293,1295,1297,1299,1301,1303,1306,1308,1312,1315,1318,1320],{"class":621,"line":740},[619,1278,1139],{"class":979},[619,1280,1142],{"class":650},[619,1282,986],{"class":640},[619,1284,989],{"class":636},[619,1286,718],{"class":640},[619,1288,644],{"class":636},[619,1290,666],{"class":723},[619,1292,726],{"class":636},[619,1294,729],{"class":640},[619,1296,732],{"class":636},[619,1298,657],{"class":636},[619,1300,1264],{"class":640},[619,1302,1171],{"class":636},[619,1304,1305],{"class":650},"map",[619,1307,986],{"class":640},[619,1309,1311],{"class":1310},"sHdIc","s",[619,1313,1314],{"class":632}," =>",[619,1316,1317],{"class":640}," s",[619,1319,1171],{"class":636},[619,1321,1322],{"class":640},"key))\n",[577,1324,1326],{"id":1325},"nuxt-auth-composable-pattern","Nuxt auth composable pattern",[561,1328,1329],{},"A practical way to wire this up — put the cleanup in a shared auth composable so it runs consistently regardless of where logout is triggered:",[599,1331,1333],{"className":613,"code":1332,"language":615,"meta":607,"style":607},"\u002F\u002F composables\u002FuseAuth.ts\nexport function useAuth() {\n  const user = useSupabaseUser()  \u002F\u002F or however you access the session\n\n  async function logout() {\n    if (user.value) {\n      \u002F\u002F Clean up local prototype data before the session ends\n      await clearProtoNamespace(user.value.id)\n      \u002F\u002F Or for multi-tenant: await clearProtoNamespace(`${tenantId}:${user.value.id}`)\n    }\n    await $fetch('\u002Fapi\u002Fauth\u002Flogout', { method: 'POST' })\n    await navigateTo('\u002Flogin')\n  }\n\n  return { user, logout }\n}\n",[565,1334,1335,1340,1353,1371,1375,1388,1410,1415,1437,1443,1449,1483,1500,1506,1511,1528],{"__ignoreMap":607},[619,1336,1337],{"class":621,"line":622},[619,1338,1339],{"class":625},"\u002F\u002F composables\u002FuseAuth.ts\n",[619,1341,1342,1344,1346,1349,1351],{"class":621,"line":629},[619,1343,1226],{"class":979},[619,1345,936],{"class":632},[619,1347,1348],{"class":650}," useAuth",[619,1350,942],{"class":636},[619,1352,945],{"class":636},[619,1354,1355,1357,1360,1362,1365,1368],{"class":621,"line":677},[619,1356,950],{"class":632},[619,1358,1359],{"class":640}," user",[619,1361,647],{"class":636},[619,1363,1364],{"class":650}," useSupabaseUser",[619,1366,1367],{"class":662},"()  ",[619,1369,1370],{"class":625},"\u002F\u002F or however you access the session\n",[619,1372,1373],{"class":621,"line":684},[619,1374,681],{"emptyLinePlaceholder":680},[619,1376,1377,1380,1382,1384,1386],{"class":621,"line":690},[619,1378,1379],{"class":632},"  async",[619,1381,936],{"class":632},[619,1383,939],{"class":650},[619,1385,942],{"class":636},[619,1387,945],{"class":636},[619,1389,1390,1393,1396,1399,1401,1404,1407],{"class":621,"line":740},[619,1391,1392],{"class":979},"    if",[619,1394,1395],{"class":662}," (",[619,1397,1398],{"class":640},"user",[619,1400,1171],{"class":636},[619,1402,1403],{"class":640},"value",[619,1405,1406],{"class":662},") ",[619,1408,1409],{"class":636},"{\n",[619,1411,1412],{"class":621,"line":745},[619,1413,1414],{"class":625},"      \u002F\u002F Clean up local prototype data before the session ends\n",[619,1416,1417,1420,1422,1424,1426,1428,1430,1432,1435],{"class":621,"line":751},[619,1418,1419],{"class":979},"      await",[619,1421,983],{"class":650},[619,1423,986],{"class":662},[619,1425,1398],{"class":640},[619,1427,1171],{"class":636},[619,1429,1403],{"class":640},[619,1431,1171],{"class":636},[619,1433,1434],{"class":640},"id",[619,1436,674],{"class":662},[619,1438,1440],{"class":621,"line":1439},9,[619,1441,1442],{"class":625},"      \u002F\u002F Or for multi-tenant: await clearProtoNamespace(`${tenantId}:${user.value.id}`)\n",[619,1444,1446],{"class":621,"line":1445},10,[619,1447,1448],{"class":636},"    }\n",[619,1450,1452,1455,1457,1459,1461,1463,1465,1467,1469,1471,1473,1475,1477,1479,1481],{"class":621,"line":1451},11,[619,1453,1454],{"class":979},"    await",[619,1456,1014],{"class":650},[619,1458,986],{"class":662},[619,1460,1019],{"class":636},[619,1462,1022],{"class":723},[619,1464,1019],{"class":636},[619,1466,657],{"class":636},[619,1468,637],{"class":636},[619,1470,1031],{"class":662},[619,1472,666],{"class":636},[619,1474,1036],{"class":636},[619,1476,1039],{"class":723},[619,1478,1019],{"class":636},[619,1480,735],{"class":636},[619,1482,674],{"class":662},[619,1484,1486,1488,1490,1492,1494,1496,1498],{"class":621,"line":1485},12,[619,1487,1454],{"class":979},[619,1489,1052],{"class":650},[619,1491,986],{"class":662},[619,1493,1019],{"class":636},[619,1495,1059],{"class":723},[619,1497,1019],{"class":636},[619,1499,674],{"class":662},[619,1501,1503],{"class":621,"line":1502},13,[619,1504,1505],{"class":636},"  }\n",[619,1507,1509],{"class":621,"line":1508},14,[619,1510,681],{"emptyLinePlaceholder":680},[619,1512,1514,1517,1519,1521,1523,1525],{"class":621,"line":1513},15,[619,1515,1516],{"class":979},"  return",[619,1518,637],{"class":636},[619,1520,1359],{"class":640},[619,1522,657],{"class":636},[619,1524,939],{"class":640},[619,1526,1527],{"class":636}," }\n",[619,1529,1531],{"class":621,"line":1530},16,[619,1532,1068],{"class":636},[577,1534,1536],{"id":1535},"what-cleanup-does","What cleanup does",[561,1538,1539],{},"Both utilities perform the same teardown steps for each matching document:",[1541,1542,1543,1546,1553,1559,1566,1572,1575],"ol",{},[881,1544,1545],{},"Cancel any pending debounced server-push timer",[881,1547,1548,1549,1552],{},"Remove the ",[565,1550,1551],{},"unhandledrejection"," listener used for corruption detection",[881,1554,1555,1556],{},"Close the ",[565,1557,1558],{},"BroadcastChannel",[881,1560,1561,1562,1565],{},"Destroy the ",[565,1563,1564],{},"IndexeddbPersistence"," provider",[881,1567,1561,1568,1571],{},[565,1569,1570],{},"Y.Doc"," in memory",[881,1573,1574],{},"Remove all entries from the internal document, provider, and ref-count caches",[881,1576,1577],{},"Delete the IndexedDB database from disk",[561,1579,1580],{},"After cleanup, the next login with the same namespace starts from a clean state — exactly as if it were a first-time user on this device.",[1582,1583,1584],"style",{},"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 .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 .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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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 .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":607,"searchDepth":629,"depth":629,"links":1586},[1587,1589,1590,1596,1597],{"id":579,"depth":629,"text":1588},"The namespace option",{"id":862,"depth":629,"text":863},{"id":908,"depth":629,"text":909,"children":1591},[1592,1594],{"id":916,"depth":677,"text":1593},"clearProtoNamespace(namespace) — recommended for most apps",{"id":1085,"depth":677,"text":1595},"clearProtoKeys(namespace, schemaKeys) — cross-browser",{"id":1325,"depth":629,"text":1326},{"id":1535,"depth":629,"text":1536},"How to scope Y.js documents per user, tenant, or workspace — and how to clean up IndexedDB on logout.","md",null,{},{"title":464},{"title":552,"description":1598},"YklwtDBlwVifiCMPcP8o6PhyJ9-7vhsijoqNDU92ufU",[1606,1608],{"title":460,"path":461,"stem":462,"description":1607,"children":-1},"How Y.js documents grow over time, how garbage collection compacts them, and what to expect for real-world prototyping workloads.",{"title":468,"path":469,"stem":470,"description":1609,"children":-1},"How to encrypt IndexedDB data with AES-GCM so local storage is unreadable without the key — even via DevTools or direct file access.",1792254332136]