[{"data":1,"prerenderedAt":5487},["ShallowReactive",2],{"navigation":3,"\u002Fservices\u002Fblobs":927,"mdc--m8qwwq-key":5447,"mdc-m2kxr4-key":5463,"mdc-tglakv-key":5475},[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":621,"access":12,"apiToc":929,"body":930,"category":5438,"description":5439,"extension":5440,"meta":5441,"navigation":5438,"nest":5442,"path":622,"seo":5443,"sinceVersion":5438,"status":5444,"stem":623,"subtitle":5438,"tier":5445,"tocExternal":5438,"__hash__":5446},"docs\u002Fservices\u002Fblobs.md",false,{"type":931,"value":932,"toc":5407},"minimark",[933,936,940,945,978,1001,1005,1044,1048,1331,1335,1340,1349,1637,1798,1834,1845,1849,2046,2068,2072,2083,2241,2385,2428,2434,2446,2489,2512,2520,2558,2744,2757,2761,2792,2797,2913,3172,3176,3186,3306,3321,3421,3577,3592,3645,3850,3857,4037,4041,4049,4397,4424,4430,4543,4549,4614,4620,4626,4774,4799,4804,4825,4903,4909,4928,5007,5013,5028,5108,5115,5119,5144,5148,5321,5325,5403],[934,935,621],"h1",{"id":621},[937,938],"service-meta",{":rows":939},"[{\"label\":\"Subpath\",\"value\":\"`@noy-db\u002Fhub\u002Fblobs`\"},{\"label\":\"Factory\",\"value\":\"`withBlobs()`\"},{\"label\":\"Layer\",\"value\":\"`with-shape`\"}]",[941,942,944],"h2",{"id":943},"what-it-does","What it does",[946,947,948,949,953,954,958,959,962,963,967,968,967,971,974,975,977],"p",{},"Blobs let you attach binary files — PDFs, images, audio — to the records of a noy-db\n",[950,951,952],"strong",{},"vault"," (the end-to-end-encrypted document store; see\n",[955,956,957],"a",{"href":48},"Vaults & collections","). Each record carries named\n",[950,960,961],{},"slots"," (",[964,965,966],"code",{},"'receipt'",", ",[964,969,970],{},"'avatar'",[964,972,973],{},"'contract'",", …), and like everything in noy-db the\nbytes are encrypted client-side before the storage backend ever sees them\n(",[955,976,21],{"href":66},").",[946,979,980,981,984,985,988,989,962,992,996,997,1000],{},"Storage is ",[950,982,983],{},"content-addressed"," — a file is identified by a keyed hash of its bytes\n(",[964,986,987],{},"eTag = HMAC-SHA-256(blob key, plaintext)","), so two records attaching the same file\nshare one stored copy, and the backend cannot recognize known content because the hash\nis keyed. Large files are split into chunks (256 KB by default), and each chunk is\nencrypted with AES-256-GCM whose ",[950,990,991],{},"AAD",[993,994,995],"em",{},"additional authenticated data"," — a value the\nciphertext is cryptographically bound to) is ",[964,998,999],{},"{eTag}:{index}:{count}",": a store that\nreorders, substitutes, or truncates chunks produces ciphertext that fails to decrypt.\nMIME types are sniffed from magic bytes when you don't provide one, compressible\npayloads are gzipped before encryption, and a consumer-scheduled compaction pass\nenforces retention policies. The whole service is ~2,376 LOC that stay out of your\nbundle until you opt in.",[941,1002,1004],{"id":1003},"prerequisites","Prerequisites",[1006,1007,1008,1023],"ul",{},[1009,1010,1011,1014,1015,1018,1019,1022],"li",{},[950,1012,1013],{},"None"," — ",[964,1016,1017],{},"withBlobs()"," alone enables ",[964,1020,1021],{},"collection.blob(id)"," slots.",[1009,1024,1025,1028,1029,1032,1033,1036,1037,1040,1041,1043],{},[993,1026,1027],{},"For erasure flows only:"," crypto-shredding blob content via ",[964,1030,1031],{},"forget()"," pairs ",[964,1034,1035],{},"historyStrategy: withHistory()"," (the erasure proof) with ",[964,1038,1039],{},"forgetStrategy: withForget()"," — see ",[955,1042,685],{"href":686},".",[941,1045,1047],{"id":1046},"opt-in","Opt in",[1049,1050,1055],"pre",{"className":1051,"code":1052,"language":1053,"meta":1054,"style":1054},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createNoydb } from '@noy-db\u002Fhub'\nimport { withBlobs } from '@noy-db\u002Fhub\u002Fblobs'\n\nconst db = await createNoydb({\n  user: 'alice',                    \u002F\u002F omitting `store` uses the built-in in-memory store;\n  secret: 'alice-secret-2026',  \u002F\u002F pass to-file \u002F to-browser-idb \u002F … in production\n  blobsStrategy: withBlobs(),\n})\nconst vault = await db.openVault('books')\n\ninterface Invoice { id: string; ref: string; reviewed?: boolean }\nconst invoices = vault.collection\u003CInvoice>('invoices')\n","ts","",[964,1056,1057,1090,1111,1118,1143,1168,1188,1204,1213,1244,1249,1293],{"__ignoreMap":1054},[1058,1059,1062,1066,1070,1074,1077,1080,1083,1087],"span",{"class":1060,"line":1061},"line",1,[1058,1063,1065],{"class":1064},"s7zQu","import",[1058,1067,1069],{"class":1068},"sMK4o"," {",[1058,1071,1073],{"class":1072},"sTEyZ"," createNoydb",[1058,1075,1076],{"class":1068}," }",[1058,1078,1079],{"class":1064}," from",[1058,1081,1082],{"class":1068}," '",[1058,1084,1086],{"class":1085},"sfazB","@noy-db\u002Fhub",[1058,1088,1089],{"class":1068},"'\n",[1058,1091,1093,1095,1097,1100,1102,1104,1106,1109],{"class":1060,"line":1092},2,[1058,1094,1065],{"class":1064},[1058,1096,1069],{"class":1068},[1058,1098,1099],{"class":1072}," withBlobs",[1058,1101,1076],{"class":1068},[1058,1103,1079],{"class":1064},[1058,1105,1082],{"class":1068},[1058,1107,1108],{"class":1085},"@noy-db\u002Fhub\u002Fblobs",[1058,1110,1089],{"class":1068},[1058,1112,1114],{"class":1060,"line":1113},3,[1058,1115,1117],{"emptyLinePlaceholder":1116},true,"\n",[1058,1119,1121,1125,1128,1131,1134,1137,1140],{"class":1060,"line":1120},4,[1058,1122,1124],{"class":1123},"spNyl","const",[1058,1126,1127],{"class":1072}," db ",[1058,1129,1130],{"class":1068},"=",[1058,1132,1133],{"class":1064}," await",[1058,1135,1073],{"class":1136},"s2Zo4",[1058,1138,1139],{"class":1072},"(",[1058,1141,1142],{"class":1068},"{\n",[1058,1144,1146,1150,1153,1155,1158,1161,1164],{"class":1060,"line":1145},5,[1058,1147,1149],{"class":1148},"swJcz","  user",[1058,1151,1152],{"class":1068},":",[1058,1154,1082],{"class":1068},[1058,1156,1157],{"class":1085},"alice",[1058,1159,1160],{"class":1068},"'",[1058,1162,1163],{"class":1068},",",[1058,1165,1167],{"class":1166},"sHwdD","                    \u002F\u002F omitting `store` uses the built-in in-memory store;\n",[1058,1169,1171,1174,1176,1178,1181,1183,1185],{"class":1060,"line":1170},6,[1058,1172,1173],{"class":1148},"  secret",[1058,1175,1152],{"class":1068},[1058,1177,1082],{"class":1068},[1058,1179,1180],{"class":1085},"alice-secret-2026",[1058,1182,1160],{"class":1068},[1058,1184,1163],{"class":1068},[1058,1186,1187],{"class":1166},"  \u002F\u002F pass to-file \u002F to-browser-idb \u002F … in production\n",[1058,1189,1191,1194,1196,1198,1201],{"class":1060,"line":1190},7,[1058,1192,1193],{"class":1148},"  blobsStrategy",[1058,1195,1152],{"class":1068},[1058,1197,1099],{"class":1136},[1058,1199,1200],{"class":1072},"()",[1058,1202,1203],{"class":1068},",\n",[1058,1205,1207,1210],{"class":1060,"line":1206},8,[1058,1208,1209],{"class":1068},"}",[1058,1211,1212],{"class":1072},")\n",[1058,1214,1216,1218,1221,1223,1225,1228,1230,1233,1235,1237,1240,1242],{"class":1060,"line":1215},9,[1058,1217,1124],{"class":1123},[1058,1219,1220],{"class":1072}," vault ",[1058,1222,1130],{"class":1068},[1058,1224,1133],{"class":1064},[1058,1226,1227],{"class":1072}," db",[1058,1229,1043],{"class":1068},[1058,1231,1232],{"class":1136},"openVault",[1058,1234,1139],{"class":1072},[1058,1236,1160],{"class":1068},[1058,1238,1239],{"class":1085},"books",[1058,1241,1160],{"class":1068},[1058,1243,1212],{"class":1072},[1058,1245,1247],{"class":1060,"line":1246},10,[1058,1248,1117],{"emptyLinePlaceholder":1116},[1058,1250,1252,1255,1259,1261,1264,1266,1269,1272,1275,1277,1279,1281,1284,1287,1290],{"class":1060,"line":1251},11,[1058,1253,1254],{"class":1123},"interface",[1058,1256,1258],{"class":1257},"sBMFI"," Invoice",[1058,1260,1069],{"class":1068},[1058,1262,1263],{"class":1148}," id",[1058,1265,1152],{"class":1068},[1058,1267,1268],{"class":1257}," string",[1058,1270,1271],{"class":1068},";",[1058,1273,1274],{"class":1148}," ref",[1058,1276,1152],{"class":1068},[1058,1278,1268],{"class":1257},[1058,1280,1271],{"class":1068},[1058,1282,1283],{"class":1148}," reviewed",[1058,1285,1286],{"class":1068},"?:",[1058,1288,1289],{"class":1257}," boolean",[1058,1291,1292],{"class":1068}," }\n",[1058,1294,1296,1298,1301,1303,1306,1308,1311,1314,1317,1320,1322,1324,1327,1329],{"class":1060,"line":1295},12,[1058,1297,1124],{"class":1123},[1058,1299,1300],{"class":1072}," invoices ",[1058,1302,1130],{"class":1068},[1058,1304,1305],{"class":1072}," vault",[1058,1307,1043],{"class":1068},[1058,1309,1310],{"class":1136},"collection",[1058,1312,1313],{"class":1068},"\u003C",[1058,1315,1316],{"class":1257},"Invoice",[1058,1318,1319],{"class":1068},">",[1058,1321,1139],{"class":1072},[1058,1323,1160],{"class":1068},[1058,1325,1326],{"class":1085},"invoices",[1058,1328,1160],{"class":1068},[1058,1330,1212],{"class":1072},[941,1332,1334],{"id":1333},"usage","Usage",[1336,1337,1339],"h3",{"id":1338},"attach-list-read-delete","Attach, list, read, delete",[946,1341,1342,1344,1345,1348],{},[964,1343,1021],{}," returns a ",[964,1346,1347],{},"BlobSet"," — the handle for every slot on that record.\nNo I\u002FO happens until you call a method.",[1049,1350,1352],{"className":1051,"code":1351,"language":1053,"meta":1054,"style":1054},"await invoices.put('inv-001', { id: 'inv-001', ref: 'INV-001' })\n\nconst pdfBytes = new Uint8Array(await fetch('\u002Freceipt-2026-06.pdf').then(r => r.arrayBuffer()))\n\nconst blobs = invoices.blob('inv-001')\nawait blobs.put('receipt', pdfBytes, {\n  mimeType: 'application\u002Fpdf',            \u002F\u002F omit to auto-detect from magic bytes\n  filename: 'receipt-2026-06.pdf',        \u002F\u002F display\u002Fdownload name; defaults to the slot name\n})\n\nconst bytes = await blobs.get('receipt')\n\u002F\u002F → Uint8Array(48213) — the decrypted original bytes; null if the slot does not exist\n\nconst slots = await blobs.list()\n",[964,1353,1354,1407,1411,1470,1474,1499,1529,1548,1567,1573,1577,1605,1610,1615],{"__ignoreMap":1054},[1058,1355,1356,1359,1362,1364,1367,1369,1371,1374,1376,1378,1380,1382,1384,1386,1388,1390,1392,1394,1396,1398,1401,1403,1405],{"class":1060,"line":1061},[1058,1357,1358],{"class":1064},"await",[1058,1360,1361],{"class":1072}," invoices",[1058,1363,1043],{"class":1068},[1058,1365,1366],{"class":1136},"put",[1058,1368,1139],{"class":1072},[1058,1370,1160],{"class":1068},[1058,1372,1373],{"class":1085},"inv-001",[1058,1375,1160],{"class":1068},[1058,1377,1163],{"class":1068},[1058,1379,1069],{"class":1068},[1058,1381,1263],{"class":1148},[1058,1383,1152],{"class":1068},[1058,1385,1082],{"class":1068},[1058,1387,1373],{"class":1085},[1058,1389,1160],{"class":1068},[1058,1391,1163],{"class":1068},[1058,1393,1274],{"class":1148},[1058,1395,1152],{"class":1068},[1058,1397,1082],{"class":1068},[1058,1399,1400],{"class":1085},"INV-001",[1058,1402,1160],{"class":1068},[1058,1404,1076],{"class":1068},[1058,1406,1212],{"class":1072},[1058,1408,1409],{"class":1060,"line":1092},[1058,1410,1117],{"emptyLinePlaceholder":1116},[1058,1412,1413,1415,1418,1420,1423,1426,1428,1430,1433,1435,1437,1440,1442,1445,1447,1450,1452,1456,1459,1462,1464,1467],{"class":1060,"line":1113},[1058,1414,1124],{"class":1123},[1058,1416,1417],{"class":1072}," pdfBytes ",[1058,1419,1130],{"class":1068},[1058,1421,1422],{"class":1068}," new",[1058,1424,1425],{"class":1136}," Uint8Array",[1058,1427,1139],{"class":1072},[1058,1429,1358],{"class":1064},[1058,1431,1432],{"class":1136}," fetch",[1058,1434,1139],{"class":1072},[1058,1436,1160],{"class":1068},[1058,1438,1439],{"class":1085},"\u002Freceipt-2026-06.pdf",[1058,1441,1160],{"class":1068},[1058,1443,1444],{"class":1072},")",[1058,1446,1043],{"class":1068},[1058,1448,1449],{"class":1136},"then",[1058,1451,1139],{"class":1072},[1058,1453,1455],{"class":1454},"sHdIc","r",[1058,1457,1458],{"class":1123}," =>",[1058,1460,1461],{"class":1072}," r",[1058,1463,1043],{"class":1068},[1058,1465,1466],{"class":1136},"arrayBuffer",[1058,1468,1469],{"class":1072},"()))\n",[1058,1471,1472],{"class":1060,"line":1120},[1058,1473,1117],{"emptyLinePlaceholder":1116},[1058,1475,1476,1478,1481,1483,1485,1487,1489,1491,1493,1495,1497],{"class":1060,"line":1145},[1058,1477,1124],{"class":1123},[1058,1479,1480],{"class":1072}," blobs ",[1058,1482,1130],{"class":1068},[1058,1484,1361],{"class":1072},[1058,1486,1043],{"class":1068},[1058,1488,133],{"class":1136},[1058,1490,1139],{"class":1072},[1058,1492,1160],{"class":1068},[1058,1494,1373],{"class":1085},[1058,1496,1160],{"class":1068},[1058,1498,1212],{"class":1072},[1058,1500,1501,1503,1506,1508,1510,1512,1514,1517,1519,1521,1524,1526],{"class":1060,"line":1170},[1058,1502,1358],{"class":1064},[1058,1504,1505],{"class":1072}," blobs",[1058,1507,1043],{"class":1068},[1058,1509,1366],{"class":1136},[1058,1511,1139],{"class":1072},[1058,1513,1160],{"class":1068},[1058,1515,1516],{"class":1085},"receipt",[1058,1518,1160],{"class":1068},[1058,1520,1163],{"class":1068},[1058,1522,1523],{"class":1072}," pdfBytes",[1058,1525,1163],{"class":1068},[1058,1527,1528],{"class":1068}," {\n",[1058,1530,1531,1534,1536,1538,1541,1543,1545],{"class":1060,"line":1190},[1058,1532,1533],{"class":1148},"  mimeType",[1058,1535,1152],{"class":1068},[1058,1537,1082],{"class":1068},[1058,1539,1540],{"class":1085},"application\u002Fpdf",[1058,1542,1160],{"class":1068},[1058,1544,1163],{"class":1068},[1058,1546,1547],{"class":1166},"            \u002F\u002F omit to auto-detect from magic bytes\n",[1058,1549,1550,1553,1555,1557,1560,1562,1564],{"class":1060,"line":1206},[1058,1551,1552],{"class":1148},"  filename",[1058,1554,1152],{"class":1068},[1058,1556,1082],{"class":1068},[1058,1558,1559],{"class":1085},"receipt-2026-06.pdf",[1058,1561,1160],{"class":1068},[1058,1563,1163],{"class":1068},[1058,1565,1566],{"class":1166},"        \u002F\u002F display\u002Fdownload name; defaults to the slot name\n",[1058,1568,1569,1571],{"class":1060,"line":1215},[1058,1570,1209],{"class":1068},[1058,1572,1212],{"class":1072},[1058,1574,1575],{"class":1060,"line":1246},[1058,1576,1117],{"emptyLinePlaceholder":1116},[1058,1578,1579,1581,1584,1586,1588,1590,1592,1595,1597,1599,1601,1603],{"class":1060,"line":1251},[1058,1580,1124],{"class":1123},[1058,1582,1583],{"class":1072}," bytes ",[1058,1585,1130],{"class":1068},[1058,1587,1133],{"class":1064},[1058,1589,1505],{"class":1072},[1058,1591,1043],{"class":1068},[1058,1593,1594],{"class":1136},"get",[1058,1596,1139],{"class":1072},[1058,1598,1160],{"class":1068},[1058,1600,1516],{"class":1085},[1058,1602,1160],{"class":1068},[1058,1604,1212],{"class":1072},[1058,1606,1607],{"class":1060,"line":1295},[1058,1608,1609],{"class":1166},"\u002F\u002F → Uint8Array(48213) — the decrypted original bytes; null if the slot does not exist\n",[1058,1611,1613],{"class":1060,"line":1612},13,[1058,1614,1117],{"emptyLinePlaceholder":1116},[1058,1616,1618,1620,1623,1625,1627,1629,1631,1634],{"class":1060,"line":1617},14,[1058,1619,1124],{"class":1123},[1058,1621,1622],{"class":1072}," slots ",[1058,1624,1130],{"class":1068},[1058,1626,1133],{"class":1064},[1058,1628,1505],{"class":1072},[1058,1630,1043],{"class":1068},[1058,1632,1633],{"class":1136},"list",[1058,1635,1636],{"class":1072},"()\n",[1049,1638,1641],{"className":1639,"code":1640,"language":141,"meta":1054,"style":1054},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[\n  {\n    \"name\": \"receipt\",\n    \"eTag\": \"9f2c41d0e6a8b37c51f0d2e94ab6c8d1…\",\n    \"filename\": \"receipt-2026-06.pdf\",\n    \"size\": 48213,\n    \"mimeType\": \"application\u002Fpdf\",\n    \"uploadedAt\": \"2026-07-08T09:30:00.000Z\",\n    \"uploadedBy\": \"alice\"\n  }\n]\n",[964,1642,1643,1648,1653,1675,1695,1714,1731,1750,1770,1788,1793],{"__ignoreMap":1054},[1058,1644,1645],{"class":1060,"line":1061},[1058,1646,1647],{"class":1068},"[\n",[1058,1649,1650],{"class":1060,"line":1092},[1058,1651,1652],{"class":1068},"  {\n",[1058,1654,1655,1658,1661,1664,1666,1669,1671,1673],{"class":1060,"line":1113},[1058,1656,1657],{"class":1068},"    \"",[1058,1659,1660],{"class":1123},"name",[1058,1662,1663],{"class":1068},"\"",[1058,1665,1152],{"class":1068},[1058,1667,1668],{"class":1068}," \"",[1058,1670,1516],{"class":1085},[1058,1672,1663],{"class":1068},[1058,1674,1203],{"class":1068},[1058,1676,1677,1679,1682,1684,1686,1688,1691,1693],{"class":1060,"line":1120},[1058,1678,1657],{"class":1068},[1058,1680,1681],{"class":1123},"eTag",[1058,1683,1663],{"class":1068},[1058,1685,1152],{"class":1068},[1058,1687,1668],{"class":1068},[1058,1689,1690],{"class":1085},"9f2c41d0e6a8b37c51f0d2e94ab6c8d1…",[1058,1692,1663],{"class":1068},[1058,1694,1203],{"class":1068},[1058,1696,1697,1699,1702,1704,1706,1708,1710,1712],{"class":1060,"line":1145},[1058,1698,1657],{"class":1068},[1058,1700,1701],{"class":1123},"filename",[1058,1703,1663],{"class":1068},[1058,1705,1152],{"class":1068},[1058,1707,1668],{"class":1068},[1058,1709,1559],{"class":1085},[1058,1711,1663],{"class":1068},[1058,1713,1203],{"class":1068},[1058,1715,1716,1718,1721,1723,1725,1729],{"class":1060,"line":1170},[1058,1717,1657],{"class":1068},[1058,1719,1720],{"class":1123},"size",[1058,1722,1663],{"class":1068},[1058,1724,1152],{"class":1068},[1058,1726,1728],{"class":1727},"sbssI"," 48213",[1058,1730,1203],{"class":1068},[1058,1732,1733,1735,1738,1740,1742,1744,1746,1748],{"class":1060,"line":1190},[1058,1734,1657],{"class":1068},[1058,1736,1737],{"class":1123},"mimeType",[1058,1739,1663],{"class":1068},[1058,1741,1152],{"class":1068},[1058,1743,1668],{"class":1068},[1058,1745,1540],{"class":1085},[1058,1747,1663],{"class":1068},[1058,1749,1203],{"class":1068},[1058,1751,1752,1754,1757,1759,1761,1763,1766,1768],{"class":1060,"line":1206},[1058,1753,1657],{"class":1068},[1058,1755,1756],{"class":1123},"uploadedAt",[1058,1758,1663],{"class":1068},[1058,1760,1152],{"class":1068},[1058,1762,1668],{"class":1068},[1058,1764,1765],{"class":1085},"2026-07-08T09:30:00.000Z",[1058,1767,1663],{"class":1068},[1058,1769,1203],{"class":1068},[1058,1771,1772,1774,1777,1779,1781,1783,1785],{"class":1060,"line":1215},[1058,1773,1657],{"class":1068},[1058,1775,1776],{"class":1123},"uploadedBy",[1058,1778,1663],{"class":1068},[1058,1780,1152],{"class":1068},[1058,1782,1668],{"class":1068},[1058,1784,1157],{"class":1085},[1058,1786,1787],{"class":1068},"\"\n",[1058,1789,1790],{"class":1060,"line":1246},[1058,1791,1792],{"class":1068},"  }\n",[1058,1794,1795],{"class":1060,"line":1251},[1058,1796,1797],{"class":1068},"]\n",[1049,1799,1801],{"className":1051,"code":1800,"language":1053,"meta":1054,"style":1054},"await blobs.delete('receipt')\n\u002F\u002F → void — removes the slot; the underlying chunks are freed once no other\n\u002F\u002F   slot or published version references the same content\n",[964,1802,1803,1824,1829],{"__ignoreMap":1054},[1058,1804,1805,1807,1809,1811,1814,1816,1818,1820,1822],{"class":1060,"line":1061},[1058,1806,1358],{"class":1064},[1058,1808,1505],{"class":1072},[1058,1810,1043],{"class":1068},[1058,1812,1813],{"class":1136},"delete",[1058,1815,1139],{"class":1072},[1058,1817,1160],{"class":1068},[1058,1819,1516],{"class":1085},[1058,1821,1160],{"class":1068},[1058,1823,1212],{"class":1072},[1058,1825,1826],{"class":1060,"line":1092},[1058,1827,1828],{"class":1166},"\u002F\u002F → void — removes the slot; the underlying chunks are freed once no other\n",[1058,1830,1831],{"class":1060,"line":1113},[1058,1832,1833],{"class":1166},"\u002F\u002F   slot or published version references the same content\n",[946,1835,1836,1837,1840,1841,1844],{},"A record can hold any number of slots (",[964,1838,1839],{},".put('receipt', …)"," and ",[964,1842,1843],{},".put('contract', …)","),\nand because storage is content-addressed, uploading the same bytes to two different\nrecords stores the chunks once and bumps a reference count.",[1336,1846,1848],{"id":1847},"serve-to-a-browser","Serve to a browser",[1049,1850,1852],{"className":1051,"code":1851,"language":1053,"meta":1054,"style":1054},"const response = await blobs.response('receipt', { inline: true })\n\u002F\u002F → Response — body streams the decrypted bytes; headers:\n\u002F\u002F   Content-Type: application\u002Fpdf\n\u002F\u002F   Content-Length: 48213\n\u002F\u002F   Content-Disposition: inline; filename=\"receipt-2026-06.pdf\"\n\u002F\u002F   ETag: \"9f2c41d0e6a8b37c51f0d2e94ab6c8d1…\"\n\u002F\u002F   (null if the slot does not exist; omit `inline` for attachment\u002Fdownload)\n\nconst built = await blobs.objectURL('receipt')\n\u002F\u002F → { url: 'blob:https:\u002F\u002Fapp.example\u002F1f2e0c9a-…', revoke: [Function] }\n\u002F\u002F   (null if the slot does not exist)\nconst img = document.querySelector\u003CHTMLImageElement>('#receipt-preview')!\nimg.src = built!.url\n\u002F\u002F later — the caller owns the lifetime:\nbuilt!.revoke()\n",[964,1853,1854,1897,1902,1907,1912,1917,1922,1927,1931,1959,1964,1969,2007,2028,2033],{"__ignoreMap":1054},[1058,1855,1856,1858,1861,1863,1865,1867,1869,1872,1874,1876,1878,1880,1882,1884,1887,1889,1893,1895],{"class":1060,"line":1061},[1058,1857,1124],{"class":1123},[1058,1859,1860],{"class":1072}," response ",[1058,1862,1130],{"class":1068},[1058,1864,1133],{"class":1064},[1058,1866,1505],{"class":1072},[1058,1868,1043],{"class":1068},[1058,1870,1871],{"class":1136},"response",[1058,1873,1139],{"class":1072},[1058,1875,1160],{"class":1068},[1058,1877,1516],{"class":1085},[1058,1879,1160],{"class":1068},[1058,1881,1163],{"class":1068},[1058,1883,1069],{"class":1068},[1058,1885,1886],{"class":1148}," inline",[1058,1888,1152],{"class":1068},[1058,1890,1892],{"class":1891},"sfNiH"," true",[1058,1894,1076],{"class":1068},[1058,1896,1212],{"class":1072},[1058,1898,1899],{"class":1060,"line":1092},[1058,1900,1901],{"class":1166},"\u002F\u002F → Response — body streams the decrypted bytes; headers:\n",[1058,1903,1904],{"class":1060,"line":1113},[1058,1905,1906],{"class":1166},"\u002F\u002F   Content-Type: application\u002Fpdf\n",[1058,1908,1909],{"class":1060,"line":1120},[1058,1910,1911],{"class":1166},"\u002F\u002F   Content-Length: 48213\n",[1058,1913,1914],{"class":1060,"line":1145},[1058,1915,1916],{"class":1166},"\u002F\u002F   Content-Disposition: inline; filename=\"receipt-2026-06.pdf\"\n",[1058,1918,1919],{"class":1060,"line":1170},[1058,1920,1921],{"class":1166},"\u002F\u002F   ETag: \"9f2c41d0e6a8b37c51f0d2e94ab6c8d1…\"\n",[1058,1923,1924],{"class":1060,"line":1190},[1058,1925,1926],{"class":1166},"\u002F\u002F   (null if the slot does not exist; omit `inline` for attachment\u002Fdownload)\n",[1058,1928,1929],{"class":1060,"line":1206},[1058,1930,1117],{"emptyLinePlaceholder":1116},[1058,1932,1933,1935,1938,1940,1942,1944,1946,1949,1951,1953,1955,1957],{"class":1060,"line":1215},[1058,1934,1124],{"class":1123},[1058,1936,1937],{"class":1072}," built ",[1058,1939,1130],{"class":1068},[1058,1941,1133],{"class":1064},[1058,1943,1505],{"class":1072},[1058,1945,1043],{"class":1068},[1058,1947,1948],{"class":1136},"objectURL",[1058,1950,1139],{"class":1072},[1058,1952,1160],{"class":1068},[1058,1954,1516],{"class":1085},[1058,1956,1160],{"class":1068},[1058,1958,1212],{"class":1072},[1058,1960,1961],{"class":1060,"line":1246},[1058,1962,1963],{"class":1166},"\u002F\u002F → { url: 'blob:https:\u002F\u002Fapp.example\u002F1f2e0c9a-…', revoke: [Function] }\n",[1058,1965,1966],{"class":1060,"line":1251},[1058,1967,1968],{"class":1166},"\u002F\u002F   (null if the slot does not exist)\n",[1058,1970,1971,1973,1976,1978,1981,1983,1986,1988,1991,1993,1995,1997,2000,2002,2004],{"class":1060,"line":1295},[1058,1972,1124],{"class":1123},[1058,1974,1975],{"class":1072}," img ",[1058,1977,1130],{"class":1068},[1058,1979,1980],{"class":1072}," document",[1058,1982,1043],{"class":1068},[1058,1984,1985],{"class":1136},"querySelector",[1058,1987,1313],{"class":1068},[1058,1989,1990],{"class":1257},"HTMLImageElement",[1058,1992,1319],{"class":1068},[1058,1994,1139],{"class":1072},[1058,1996,1160],{"class":1068},[1058,1998,1999],{"class":1085},"#receipt-preview",[1058,2001,1160],{"class":1068},[1058,2003,1444],{"class":1072},[1058,2005,2006],{"class":1068},"!\n",[1058,2008,2009,2012,2014,2017,2019,2022,2025],{"class":1060,"line":1612},[1058,2010,2011],{"class":1072},"img",[1058,2013,1043],{"class":1068},[1058,2015,2016],{"class":1072},"src ",[1058,2018,1130],{"class":1068},[1058,2020,2021],{"class":1072}," built",[1058,2023,2024],{"class":1068},"!.",[1058,2026,2027],{"class":1072},"url\n",[1058,2029,2030],{"class":1060,"line":1617},[1058,2031,2032],{"class":1166},"\u002F\u002F later — the caller owns the lifetime:\n",[1058,2034,2036,2039,2041,2044],{"class":1060,"line":2035},15,[1058,2037,2038],{"class":1072},"built",[1058,2040,2024],{"class":1068},[1058,2042,2043],{"class":1136},"revoke",[1058,2045,1636],{"class":1072},[946,2047,2048,2051,2052,2055,2056,2059,2060,2063,2064,2067],{},[964,2049,2050],{},"objectURL()"," throws where ",[964,2053,2054],{},"URL.createObjectURL"," is unavailable (Node without DOM,\nrestricted workers). If you use Vue, the ",[964,2057,2058],{},"useBlobURL"," composable in ",[964,2061,2062],{},"@noy-db\u002Fin-vue","\nwraps this with auto-revoke on reactive id change and scope dispose, and stays at\n",[964,2065,2066],{},"null"," during SSR.",[1336,2069,2071],{"id":2070},"retention-compaction","Retention & compaction",[946,2073,2074,2075,2078,2079,2082],{},"Declare per-slot policies with the collection's ",[964,2076,2077],{},"blobFields"," option, then run\n",[964,2080,2081],{},"vault.compact()"," whenever your workflow allows — a cron job, a manual \"tidy\" button,\nexport prep. noy-db never runs compaction on its own.",[1049,2084,2086],{"className":1051,"code":2085,"language":1053,"meta":1054,"style":1054},"const invoices = vault.collection\u003CInvoice>('invoices', {\n  blobFields: {\n    receipt: {\n      retainDays: 365,                          \u002F\u002F age-based TTL\n      evictWhen: (rec) => rec.reviewed === true, \u002F\u002F predicate over the decrypted record\n    },\n  },\n})\n\nconst preview = await vault.compact({ dryRun: true })\n",[964,2087,2088,2120,2129,2138,2153,2187,2192,2197,2203,2207],{"__ignoreMap":1054},[1058,2089,2090,2092,2094,2096,2098,2100,2102,2104,2106,2108,2110,2112,2114,2116,2118],{"class":1060,"line":1061},[1058,2091,1124],{"class":1123},[1058,2093,1300],{"class":1072},[1058,2095,1130],{"class":1068},[1058,2097,1305],{"class":1072},[1058,2099,1043],{"class":1068},[1058,2101,1310],{"class":1136},[1058,2103,1313],{"class":1068},[1058,2105,1316],{"class":1257},[1058,2107,1319],{"class":1068},[1058,2109,1139],{"class":1072},[1058,2111,1160],{"class":1068},[1058,2113,1326],{"class":1085},[1058,2115,1160],{"class":1068},[1058,2117,1163],{"class":1068},[1058,2119,1528],{"class":1068},[1058,2121,2122,2125,2127],{"class":1060,"line":1092},[1058,2123,2124],{"class":1148},"  blobFields",[1058,2126,1152],{"class":1068},[1058,2128,1528],{"class":1068},[1058,2130,2131,2134,2136],{"class":1060,"line":1113},[1058,2132,2133],{"class":1148},"    receipt",[1058,2135,1152],{"class":1068},[1058,2137,1528],{"class":1068},[1058,2139,2140,2143,2145,2148,2150],{"class":1060,"line":1120},[1058,2141,2142],{"class":1148},"      retainDays",[1058,2144,1152],{"class":1068},[1058,2146,2147],{"class":1727}," 365",[1058,2149,1163],{"class":1068},[1058,2151,2152],{"class":1166},"                          \u002F\u002F age-based TTL\n",[1058,2154,2155,2158,2160,2162,2165,2167,2169,2172,2174,2177,2180,2182,2184],{"class":1060,"line":1145},[1058,2156,2157],{"class":1136},"      evictWhen",[1058,2159,1152],{"class":1068},[1058,2161,962],{"class":1068},[1058,2163,2164],{"class":1454},"rec",[1058,2166,1444],{"class":1068},[1058,2168,1458],{"class":1123},[1058,2170,2171],{"class":1072}," rec",[1058,2173,1043],{"class":1068},[1058,2175,2176],{"class":1072},"reviewed ",[1058,2178,2179],{"class":1068},"===",[1058,2181,1892],{"class":1891},[1058,2183,1163],{"class":1068},[1058,2185,2186],{"class":1166}," \u002F\u002F predicate over the decrypted record\n",[1058,2188,2189],{"class":1060,"line":1170},[1058,2190,2191],{"class":1068},"    },\n",[1058,2193,2194],{"class":1060,"line":1190},[1058,2195,2196],{"class":1068},"  },\n",[1058,2198,2199,2201],{"class":1060,"line":1206},[1058,2200,1209],{"class":1068},[1058,2202,1212],{"class":1072},[1058,2204,2205],{"class":1060,"line":1215},[1058,2206,1117],{"emptyLinePlaceholder":1116},[1058,2208,2209,2211,2214,2216,2218,2220,2222,2225,2227,2230,2233,2235,2237,2239],{"class":1060,"line":1246},[1058,2210,1124],{"class":1123},[1058,2212,2213],{"class":1072}," preview ",[1058,2215,1130],{"class":1068},[1058,2217,1133],{"class":1064},[1058,2219,1305],{"class":1072},[1058,2221,1043],{"class":1068},[1058,2223,2224],{"class":1136},"compact",[1058,2226,1139],{"class":1072},[1058,2228,2229],{"class":1068},"{",[1058,2231,2232],{"class":1148}," dryRun",[1058,2234,1152],{"class":1068},[1058,2236,1892],{"class":1891},[1058,2238,1076],{"class":1068},[1058,2240,1212],{"class":1072},[1049,2242,2244],{"className":1639,"code":2243,"language":141,"meta":1054,"style":1054},"{\n  \"evicted\": 12,\n  \"records\": 480,\n  \"collections\": 1,\n  \"auditEntries\": 0,\n  \"held\": 3,\n  \"byCollection\": { \"invoices\": { \"records\": 480, \"evicted\": 12 } }\n}\n",[964,2245,2246,2250,2267,2283,2299,2315,2331,2380],{"__ignoreMap":1054},[1058,2247,2248],{"class":1060,"line":1061},[1058,2249,1142],{"class":1068},[1058,2251,2252,2255,2258,2260,2262,2265],{"class":1060,"line":1092},[1058,2253,2254],{"class":1068},"  \"",[1058,2256,2257],{"class":1123},"evicted",[1058,2259,1663],{"class":1068},[1058,2261,1152],{"class":1068},[1058,2263,2264],{"class":1727}," 12",[1058,2266,1203],{"class":1068},[1058,2268,2269,2271,2274,2276,2278,2281],{"class":1060,"line":1113},[1058,2270,2254],{"class":1068},[1058,2272,2273],{"class":1123},"records",[1058,2275,1663],{"class":1068},[1058,2277,1152],{"class":1068},[1058,2279,2280],{"class":1727}," 480",[1058,2282,1203],{"class":1068},[1058,2284,2285,2287,2290,2292,2294,2297],{"class":1060,"line":1120},[1058,2286,2254],{"class":1068},[1058,2288,2289],{"class":1123},"collections",[1058,2291,1663],{"class":1068},[1058,2293,1152],{"class":1068},[1058,2295,2296],{"class":1727}," 1",[1058,2298,1203],{"class":1068},[1058,2300,2301,2303,2306,2308,2310,2313],{"class":1060,"line":1145},[1058,2302,2254],{"class":1068},[1058,2304,2305],{"class":1123},"auditEntries",[1058,2307,1663],{"class":1068},[1058,2309,1152],{"class":1068},[1058,2311,2312],{"class":1727}," 0",[1058,2314,1203],{"class":1068},[1058,2316,2317,2319,2322,2324,2326,2329],{"class":1060,"line":1170},[1058,2318,2254],{"class":1068},[1058,2320,2321],{"class":1123},"held",[1058,2323,1663],{"class":1068},[1058,2325,1152],{"class":1068},[1058,2327,2328],{"class":1727}," 3",[1058,2330,1203],{"class":1068},[1058,2332,2333,2335,2338,2340,2342,2344,2346,2348,2350,2352,2354,2356,2358,2360,2362,2364,2366,2368,2370,2372,2374,2376,2378],{"class":1060,"line":1190},[1058,2334,2254],{"class":1068},[1058,2336,2337],{"class":1123},"byCollection",[1058,2339,1663],{"class":1068},[1058,2341,1152],{"class":1068},[1058,2343,1069],{"class":1068},[1058,2345,1668],{"class":1068},[1058,2347,1326],{"class":1257},[1058,2349,1663],{"class":1068},[1058,2351,1152],{"class":1068},[1058,2353,1069],{"class":1068},[1058,2355,1668],{"class":1068},[1058,2357,2273],{"class":1727},[1058,2359,1663],{"class":1068},[1058,2361,1152],{"class":1068},[1058,2363,2280],{"class":1727},[1058,2365,1163],{"class":1068},[1058,2367,1668],{"class":1068},[1058,2369,2257],{"class":1727},[1058,2371,1663],{"class":1068},[1058,2373,1152],{"class":1068},[1058,2375,2264],{"class":1727},[1058,2377,1076],{"class":1068},[1058,2379,1292],{"class":1068},[1058,2381,2382],{"class":1060,"line":1206},[1058,2383,2384],{"class":1068},"}\n",[946,2386,2387,2388,2391,2392,2394,2395,2397,2398,2401,2402,2405,2406,2405,2409,2412,2413,2415,2416,2419,2420,2423,2424,977],{},"In a real run (no ",[964,2389,2390],{},"dryRun",") ",[964,2393,2305],{}," equals ",[964,2396,2257],{},": every eviction writes one\ntamper-evident entry to the internal ",[964,2399,2400],{},"_blob_eviction_audit"," collection carrying the\nactor, the reason (",[964,2403,2404],{},"'ttl'"," \u002F ",[964,2407,2408],{},"'predicate'",[964,2410,2411],{},"'both'","), and the opaque eTag — no\nplaintext. ",[964,2414,2321],{}," counts slots that were due for eviction but kept by a ",[964,2417,2418],{},"legalHold"," or\n",[964,2421,2422],{},"retainUntil"," floor (see the ",[955,2425,2427],{"href":2426},"#blobfields-policy","policy table",[1336,2429,2431,2432],{"id":2430},"erasure-blobs-shred-with-forget","Erasure — blobs shred with ",[964,2433,1031],{},[946,2435,2436,2437,2441,2442,2445],{},"Compaction removes slots on a schedule; ",[955,2438,2439],{"href":686},[964,2440,1031],{}," removes them on a\nright-to-erasure request. When you crypto-shred a record with ",[964,2443,2444],{},"vault.forget(subjectId)",", the\nblob content attached to that record is shredded too — each attachment's own content key is\ndestroyed, so its encrypted chunks can never be decrypted again. A blob whose bytes another\nrecord still references (same content-addressed eTag) is retained and counted separately:",[1049,2447,2449],{"className":1051,"code":2448,"language":1053,"meta":1054,"style":1054},"const result = await vault.forget('buyer-123')\n\u002F\u002F result.blobsShredded        → 2   attachments whose content key was destroyed\n\u002F\u002F result.blobsRetainedShared  → 1   attachments kept because another record shares the bytes\n",[964,2450,2451,2479,2484],{"__ignoreMap":1054},[1058,2452,2453,2455,2458,2460,2462,2464,2466,2468,2470,2472,2475,2477],{"class":1060,"line":1061},[1058,2454,1124],{"class":1123},[1058,2456,2457],{"class":1072}," result ",[1058,2459,1130],{"class":1068},[1058,2461,1133],{"class":1064},[1058,2463,1305],{"class":1072},[1058,2465,1043],{"class":1068},[1058,2467,685],{"class":1136},[1058,2469,1139],{"class":1072},[1058,2471,1160],{"class":1068},[1058,2473,2474],{"class":1085},"buyer-123",[1058,2476,1160],{"class":1068},[1058,2478,1212],{"class":1072},[1058,2480,2481],{"class":1060,"line":1092},[1058,2482,2483],{"class":1166},"\u002F\u002F result.blobsShredded        → 2   attachments whose content key was destroyed\n",[1058,2485,2486],{"class":1060,"line":1113},[1058,2487,2488],{"class":1166},"\u002F\u002F result.blobsRetainedShared  → 1   attachments kept because another record shares the bytes\n",[946,2490,2491,2492,2495,2496,2499,2500,2502,2503,2506,2507,2509,2510,1043],{},"By ",[950,2493,2494],{},"default",", this shred runs for ",[950,2497,2498],{},"every"," collection in a blob-enabled vault — whether or\nnot the collection declared a ",[964,2501,2077],{}," policy. A record that only ever called\n",[964,2504,2505],{},".blob(id)"," directly, with no ",[964,2508,2077],{}," declaration, still has its blobs shredded on\n",[964,2511,1031],{},[2513,2514,2516,2517],"h4",{"id":2515},"scoping-the-scan-with-scopedpurge","Scoping the scan with ",[964,2518,2519],{},"scopedPurge",[946,2521,2522,2523,967,2526,2529,2530,2532,2533,2536,2537,2539,2540,2543,2544,2547,2548,2551,2552,2554,2555,2557],{},"Since ",[964,2524,2525],{},"0.3.0-pre.11",[964,2527,2528],{},"withForget({ …, scopedPurge: true })","\nturns that default off: under it, ",[964,2531,1031],{}," scans and shreds blobs ",[950,2534,2535],{},"only"," for collections\nthat declared a ",[964,2538,2077],{}," policy. An undeclared collection's blobs are skipped entirely —\nno shred call and no residue-detection listing pass, which is the performance win the opt-in\nbuys. The skip is reported, never silent: ",[964,2541,2542],{},"ForgetResult.scopedPurgeResidue"," carries a\n",[964,2545,2546],{},"{ reason: 'skipped-undeclared-blob-scan', collection, count }"," entry, where ",[964,2549,2550],{},"count"," is the\nnumber of that collection's records whose blob scan was skipped. Those blobs stay untouched\nuntil you either declare ",[964,2553,2077],{}," for the collection or turn ",[964,2556,2519],{}," back off.",[1049,2559,2561],{"className":1051,"code":2560,"language":1053,"meta":1054,"style":1054},"import { withForget } from '@noy-db\u002Fhub\u002Fforget'\nimport { withHistory } from '@noy-db\u002Fhub\u002Fhistory'\n\nconst db = await createNoydb({\n  user: 'alice',\n  secret: 'alice-secret-2026',\n  blobsStrategy: withBlobs(),\n  historyStrategy: withHistory(),                       \u002F\u002F forget() writes its erasure proof here\n  forgetStrategy: withForget({\n    subjects: { invoices: 'buyerId' },\n    scopedPurge: true,                                   \u002F\u002F only scan blobs on declared collections\n  }),\n})\n",[964,2562,2563,2583,2603,2607,2623,2637,2651,2663,2679,2692,2715,2729,2738],{"__ignoreMap":1054},[1058,2564,2565,2567,2569,2572,2574,2576,2578,2581],{"class":1060,"line":1061},[1058,2566,1065],{"class":1064},[1058,2568,1069],{"class":1068},[1058,2570,2571],{"class":1072}," withForget",[1058,2573,1076],{"class":1068},[1058,2575,1079],{"class":1064},[1058,2577,1082],{"class":1068},[1058,2579,2580],{"class":1085},"@noy-db\u002Fhub\u002Fforget",[1058,2582,1089],{"class":1068},[1058,2584,2585,2587,2589,2592,2594,2596,2598,2601],{"class":1060,"line":1092},[1058,2586,1065],{"class":1064},[1058,2588,1069],{"class":1068},[1058,2590,2591],{"class":1072}," withHistory",[1058,2593,1076],{"class":1068},[1058,2595,1079],{"class":1064},[1058,2597,1082],{"class":1068},[1058,2599,2600],{"class":1085},"@noy-db\u002Fhub\u002Fhistory",[1058,2602,1089],{"class":1068},[1058,2604,2605],{"class":1060,"line":1113},[1058,2606,1117],{"emptyLinePlaceholder":1116},[1058,2608,2609,2611,2613,2615,2617,2619,2621],{"class":1060,"line":1120},[1058,2610,1124],{"class":1123},[1058,2612,1127],{"class":1072},[1058,2614,1130],{"class":1068},[1058,2616,1133],{"class":1064},[1058,2618,1073],{"class":1136},[1058,2620,1139],{"class":1072},[1058,2622,1142],{"class":1068},[1058,2624,2625,2627,2629,2631,2633,2635],{"class":1060,"line":1145},[1058,2626,1149],{"class":1148},[1058,2628,1152],{"class":1068},[1058,2630,1082],{"class":1068},[1058,2632,1157],{"class":1085},[1058,2634,1160],{"class":1068},[1058,2636,1203],{"class":1068},[1058,2638,2639,2641,2643,2645,2647,2649],{"class":1060,"line":1170},[1058,2640,1173],{"class":1148},[1058,2642,1152],{"class":1068},[1058,2644,1082],{"class":1068},[1058,2646,1180],{"class":1085},[1058,2648,1160],{"class":1068},[1058,2650,1203],{"class":1068},[1058,2652,2653,2655,2657,2659,2661],{"class":1060,"line":1190},[1058,2654,1193],{"class":1148},[1058,2656,1152],{"class":1068},[1058,2658,1099],{"class":1136},[1058,2660,1200],{"class":1072},[1058,2662,1203],{"class":1068},[1058,2664,2665,2668,2670,2672,2674,2676],{"class":1060,"line":1206},[1058,2666,2667],{"class":1148},"  historyStrategy",[1058,2669,1152],{"class":1068},[1058,2671,2591],{"class":1136},[1058,2673,1200],{"class":1072},[1058,2675,1163],{"class":1068},[1058,2677,2678],{"class":1166},"                       \u002F\u002F forget() writes its erasure proof here\n",[1058,2680,2681,2684,2686,2688,2690],{"class":1060,"line":1215},[1058,2682,2683],{"class":1148},"  forgetStrategy",[1058,2685,1152],{"class":1068},[1058,2687,2571],{"class":1136},[1058,2689,1139],{"class":1072},[1058,2691,1142],{"class":1068},[1058,2693,2694,2697,2699,2701,2703,2705,2707,2710,2712],{"class":1060,"line":1246},[1058,2695,2696],{"class":1148},"    subjects",[1058,2698,1152],{"class":1068},[1058,2700,1069],{"class":1068},[1058,2702,1361],{"class":1148},[1058,2704,1152],{"class":1068},[1058,2706,1082],{"class":1068},[1058,2708,2709],{"class":1085},"buyerId",[1058,2711,1160],{"class":1068},[1058,2713,2714],{"class":1068}," },\n",[1058,2716,2717,2720,2722,2724,2726],{"class":1060,"line":1251},[1058,2718,2719],{"class":1148},"    scopedPurge",[1058,2721,1152],{"class":1068},[1058,2723,1892],{"class":1891},[1058,2725,1163],{"class":1068},[1058,2727,2728],{"class":1166},"                                   \u002F\u002F only scan blobs on declared collections\n",[1058,2730,2731,2734,2736],{"class":1060,"line":1295},[1058,2732,2733],{"class":1068},"  }",[1058,2735,1444],{"class":1072},[1058,2737,1203],{"class":1068},[1058,2739,2740,2742],{"class":1060,"line":1612},[1058,2741,1209],{"class":1068},[1058,2743,1212],{"class":1072},[946,2745,2746,2747,2750,2751,2753,2754,2756],{},"The declaration is read from collections ",[950,2748,2749],{},"opened in the current session",": a collection\nwhose ",[964,2752,2077],{}," config was never instantiated before the ",[964,2755,1031],{}," call counts as\nundeclared and is skipped. Open it (with its config) first.",[1336,2758,2760],{"id":2759},"tiered-blobs-content-follows-the-records-tier","Tiered blobs — content follows the record's tier",[946,2762,2522,2763,2766,2767,2770,2771,1840,2773,2775,2776,2779,2780,2783,2784,2787,2788,2791],{},[964,2764,2765],{},"0.3.0-pre.13"," (#724\u002F#741) a collection may declare ",[950,2768,2769],{},"both"," ",[964,2772,2077],{},[964,2774,872],{}," (the\n",[955,2777,2778],{"href":873},"record-elevation ladder",") — a composition that was previously\nrefused with ",[964,2781,2782],{},"UnsupportedTierCompositionError",". A blob's storage tier equals its ",[950,2785,2786],{},"owning record's","\ntier: its content key, chunk address, slot-map metadata, and published versions are all keyed under\nthat tier's ",[964,2789,2790],{},"_blob"," DEK, so an elevated record's attachment is unreadable at rest by a tier-0 key\nholder.",[946,2793,2794,2795,1043],{},"Tiered blobs are one face of the record-tier system — the model, the elevation API, and the\ncross-service map live in ",[955,2796,872],{"href":873},[1006,2798,2799,2846,2861,2898],{},[1009,2800,2801,2770,2804,2807,2808,967,2811,1203,2814,2817,2818,2821,2822,2827,2828,2831,2832,2835,2836,2838,2839,2841,2842,2845],{},[950,2802,2803],{},"Reads are tier-gated at runtime.",[964,2805,2806],{},"blob(id)"," is the tier-0 surface: ",[964,2809,2810],{},"get()",[964,2812,2813],{},"list()",[964,2815,2816],{},"blobInfo()",", and every other accessor treat an ",[950,2819,2820],{},"elevated"," record's blobs as nonexistent, for\neveryone, before any decrypt. The sanctioned cleared path is ",[950,2823,2824],{},[964,2825,2826],{},"blob(id).atTier()"," — it peeks\nthe owning record's live tier and, for an elevated record, runs the same tier-access check\n",[964,2829,2830],{},"elevate()","\u002F",[964,2833,2834],{},"putAtTier()"," use (against both the data collection and the ",[964,2837,2790],{}," collection at that\ntier) before minting any key material, then returns a ",[964,2840,1347],{}," that reads through the gate. An\nungranted caller gets ",[964,2843,2844],{},"TierNotGrantedError"," and no key is minted; owner\u002Fadmin\u002Fcustodian clear\nautomatically.",[1009,2847,2848,2770,2851,2853,2854,2857,2858,2860],{},[950,2849,2850],{},"Re-home on elevate\u002Fdemote is reversible.",[964,2852,2830],{}," re-homes a record's blobs (and published\nversions) under the destination tier's DEK; ",[964,2855,2856],{},"demote()"," restores tier-0 readability. The move is\njournaled and crash-safe (#746) — a half-moved record heals on the next tier op or blob touch.\n",[964,2859,1031],{}," of an elevated blob-owner crypto-shreds under the record's pre-tombstone tier.",[1009,2862,2863,2869,2870,2873,2874,2877,2878,2880,2881,2884,2885,2887,2888,2894,2895,2897],{},[950,2864,2865,2868],{},[964,2866,2867],{},"blobTierPolicy"," — how a shared blob behaves on elevate."," Content-addressed dedup means one\nstored object can back several records. The collection option ",[964,2871,2872],{},"blobTierPolicy?: 'isolate' | 'dedup'"," (default ",[964,2875,2876],{},"'isolate'",") chooses what happens when one co-owner elevates: ",[964,2879,2876],{}," forks a\nprivate tier-scoped copy so the co-owning tier-0 records are untouched; ",[964,2882,2883],{},"'dedup'"," (#741) leaves the\nshared object in place. Under ",[964,2886,2883],{}," the runtime read gate still hides the object from a tier-0\ncaller, but the shared chunks ",[950,2889,2890,2891,2893],{},"remain decryptable at rest under the flat ",[964,2892,2790],{}," DEK"," — a\ndocumented, accepted residue (the same class as the aggregate-inference channel). Choose ",[964,2896,2883],{},"\nonly when at-rest isolation of shared content is not required.",[1009,2899,2900,2906,2907,2909,2910,2912],{},[950,2901,2902,2905],{},[964,2903,2904],{},"perRecordKeys"," is mandatory."," A tiered collection that declares ",[964,2908,2077],{}," must set\n",[964,2911,2904],{}," — a legacy blob has no per-record key and cannot be tier-isolated, so writing one\nto a tiered collection is refused.",[1049,2914,2916],{"className":1051,"code":2915,"language":1053,"meta":1054,"style":1054},"import { withTiers } from '@noy-db\u002Fhub\u002Ftiers'\n\nconst db = await createNoydb({\n  user: 'alice',\n  secret: 'alice-secret-2026',\n  blobsStrategy: withBlobs(),\n  tiersStrategy: withTiers(),\n})\nconst vault = await db.openVault('books')\n\nconst invoices = vault.collection\u003CInvoice>('invoices', {\n  tiers: [0, 1, 2],\n  perRecordKeys: true,        \u002F\u002F required alongside blobFields on a tiered collection\n  blobTierPolicy: 'isolate',  \u002F\u002F default — fork a private copy of a shared blob on elevate\n  blobFields: { receipt: { retainDays: 365 } },\n})\n",[964,2917,2918,2938,2942,2958,2972,2986,2998,3011,3017,3043,3047,3079,3106,3120,3139,3165],{"__ignoreMap":1054},[1058,2919,2920,2922,2924,2927,2929,2931,2933,2936],{"class":1060,"line":1061},[1058,2921,1065],{"class":1064},[1058,2923,1069],{"class":1068},[1058,2925,2926],{"class":1072}," withTiers",[1058,2928,1076],{"class":1068},[1058,2930,1079],{"class":1064},[1058,2932,1082],{"class":1068},[1058,2934,2935],{"class":1085},"@noy-db\u002Fhub\u002Ftiers",[1058,2937,1089],{"class":1068},[1058,2939,2940],{"class":1060,"line":1092},[1058,2941,1117],{"emptyLinePlaceholder":1116},[1058,2943,2944,2946,2948,2950,2952,2954,2956],{"class":1060,"line":1113},[1058,2945,1124],{"class":1123},[1058,2947,1127],{"class":1072},[1058,2949,1130],{"class":1068},[1058,2951,1133],{"class":1064},[1058,2953,1073],{"class":1136},[1058,2955,1139],{"class":1072},[1058,2957,1142],{"class":1068},[1058,2959,2960,2962,2964,2966,2968,2970],{"class":1060,"line":1120},[1058,2961,1149],{"class":1148},[1058,2963,1152],{"class":1068},[1058,2965,1082],{"class":1068},[1058,2967,1157],{"class":1085},[1058,2969,1160],{"class":1068},[1058,2971,1203],{"class":1068},[1058,2973,2974,2976,2978,2980,2982,2984],{"class":1060,"line":1145},[1058,2975,1173],{"class":1148},[1058,2977,1152],{"class":1068},[1058,2979,1082],{"class":1068},[1058,2981,1180],{"class":1085},[1058,2983,1160],{"class":1068},[1058,2985,1203],{"class":1068},[1058,2987,2988,2990,2992,2994,2996],{"class":1060,"line":1170},[1058,2989,1193],{"class":1148},[1058,2991,1152],{"class":1068},[1058,2993,1099],{"class":1136},[1058,2995,1200],{"class":1072},[1058,2997,1203],{"class":1068},[1058,2999,3000,3003,3005,3007,3009],{"class":1060,"line":1190},[1058,3001,3002],{"class":1148},"  tiersStrategy",[1058,3004,1152],{"class":1068},[1058,3006,2926],{"class":1136},[1058,3008,1200],{"class":1072},[1058,3010,1203],{"class":1068},[1058,3012,3013,3015],{"class":1060,"line":1206},[1058,3014,1209],{"class":1068},[1058,3016,1212],{"class":1072},[1058,3018,3019,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039,3041],{"class":1060,"line":1215},[1058,3020,1124],{"class":1123},[1058,3022,1220],{"class":1072},[1058,3024,1130],{"class":1068},[1058,3026,1133],{"class":1064},[1058,3028,1227],{"class":1072},[1058,3030,1043],{"class":1068},[1058,3032,1232],{"class":1136},[1058,3034,1139],{"class":1072},[1058,3036,1160],{"class":1068},[1058,3038,1239],{"class":1085},[1058,3040,1160],{"class":1068},[1058,3042,1212],{"class":1072},[1058,3044,3045],{"class":1060,"line":1246},[1058,3046,1117],{"emptyLinePlaceholder":1116},[1058,3048,3049,3051,3053,3055,3057,3059,3061,3063,3065,3067,3069,3071,3073,3075,3077],{"class":1060,"line":1251},[1058,3050,1124],{"class":1123},[1058,3052,1300],{"class":1072},[1058,3054,1130],{"class":1068},[1058,3056,1305],{"class":1072},[1058,3058,1043],{"class":1068},[1058,3060,1310],{"class":1136},[1058,3062,1313],{"class":1068},[1058,3064,1316],{"class":1257},[1058,3066,1319],{"class":1068},[1058,3068,1139],{"class":1072},[1058,3070,1160],{"class":1068},[1058,3072,1326],{"class":1085},[1058,3074,1160],{"class":1068},[1058,3076,1163],{"class":1068},[1058,3078,1528],{"class":1068},[1058,3080,3081,3084,3086,3089,3092,3094,3096,3098,3101,3104],{"class":1060,"line":1295},[1058,3082,3083],{"class":1148},"  tiers",[1058,3085,1152],{"class":1068},[1058,3087,3088],{"class":1072}," [",[1058,3090,3091],{"class":1727},"0",[1058,3093,1163],{"class":1068},[1058,3095,2296],{"class":1727},[1058,3097,1163],{"class":1068},[1058,3099,3100],{"class":1727}," 2",[1058,3102,3103],{"class":1072},"]",[1058,3105,1203],{"class":1068},[1058,3107,3108,3111,3113,3115,3117],{"class":1060,"line":1612},[1058,3109,3110],{"class":1148},"  perRecordKeys",[1058,3112,1152],{"class":1068},[1058,3114,1892],{"class":1891},[1058,3116,1163],{"class":1068},[1058,3118,3119],{"class":1166},"        \u002F\u002F required alongside blobFields on a tiered collection\n",[1058,3121,3122,3125,3127,3129,3132,3134,3136],{"class":1060,"line":1617},[1058,3123,3124],{"class":1148},"  blobTierPolicy",[1058,3126,1152],{"class":1068},[1058,3128,1082],{"class":1068},[1058,3130,3131],{"class":1085},"isolate",[1058,3133,1160],{"class":1068},[1058,3135,1163],{"class":1068},[1058,3137,3138],{"class":1166},"  \u002F\u002F default — fork a private copy of a shared blob on elevate\n",[1058,3140,3141,3143,3145,3147,3150,3152,3154,3157,3159,3161,3163],{"class":1060,"line":2035},[1058,3142,2124],{"class":1148},[1058,3144,1152],{"class":1068},[1058,3146,1069],{"class":1068},[1058,3148,3149],{"class":1148}," receipt",[1058,3151,1152],{"class":1068},[1058,3153,1069],{"class":1068},[1058,3155,3156],{"class":1148}," retainDays",[1058,3158,1152],{"class":1068},[1058,3160,2147],{"class":1727},[1058,3162,1076],{"class":1068},[1058,3164,2714],{"class":1068},[1058,3166,3168,3170],{"class":1060,"line":3167},16,[1058,3169,1209],{"class":1068},[1058,3171,1212],{"class":1072},[1336,3173,3175],{"id":3174},"bulk-export","Bulk export",[946,3177,3178,3181,3182,3185],{},[964,3179,3180],{},"vault.exportBlobs(options?)"," is the framework-agnostic primitive: an async-iterable\nhandle over every blob in the vault, decrypting lazily as you pull. It checks the\ncaller's export capability once at handle creation and writes a single audit entry to\n",[964,3183,3184],{},"_export_audit"," before the first yield.",[1049,3187,3189],{"className":1051,"code":3188,"language":1053,"meta":1054,"style":1054},"const handle = vault.exportBlobs({ collections: ['invoices'] })\nfor await (const { blobId, recordRef, bytes, meta } of handle) {\n  \u002F\u002F blobId    → '9f2c41d0e6a8b37c51f0d2e94ab6c8d1…'  (the eTag)\n  \u002F\u002F recordRef → { collection: 'invoices', id: 'inv-001', slot: 'receipt' }\n  \u002F\u002F bytes     → Uint8Array(48213) — decrypted plaintext\n  \u002F\u002F meta      → { size: 48213, filename: 'receipt-2026-06.pdf',\n  \u002F\u002F               mimeType: 'application\u002Fpdf', createdAt: '2026-07-08T09:30:00.000Z' }\n  \u002F\u002F …write `bytes` to your sink: zip stream, S3 multipart, cold storage\n}\n",[964,3190,3191,3231,3272,3277,3282,3287,3292,3297,3302],{"__ignoreMap":1054},[1058,3192,3193,3195,3198,3200,3202,3204,3207,3209,3211,3214,3216,3218,3220,3222,3224,3227,3229],{"class":1060,"line":1061},[1058,3194,1124],{"class":1123},[1058,3196,3197],{"class":1072}," handle ",[1058,3199,1130],{"class":1068},[1058,3201,1305],{"class":1072},[1058,3203,1043],{"class":1068},[1058,3205,3206],{"class":1136},"exportBlobs",[1058,3208,1139],{"class":1072},[1058,3210,2229],{"class":1068},[1058,3212,3213],{"class":1148}," collections",[1058,3215,1152],{"class":1068},[1058,3217,3088],{"class":1072},[1058,3219,1160],{"class":1068},[1058,3221,1326],{"class":1085},[1058,3223,1160],{"class":1068},[1058,3225,3226],{"class":1072},"] ",[1058,3228,1209],{"class":1068},[1058,3230,1212],{"class":1072},[1058,3232,3233,3236,3238,3240,3242,3244,3247,3249,3252,3254,3257,3259,3262,3264,3267,3270],{"class":1060,"line":1092},[1058,3234,3235],{"class":1064},"for",[1058,3237,1133],{"class":1064},[1058,3239,962],{"class":1072},[1058,3241,1124],{"class":1123},[1058,3243,1069],{"class":1068},[1058,3245,3246],{"class":1072}," blobId",[1058,3248,1163],{"class":1068},[1058,3250,3251],{"class":1072}," recordRef",[1058,3253,1163],{"class":1068},[1058,3255,3256],{"class":1072}," bytes",[1058,3258,1163],{"class":1068},[1058,3260,3261],{"class":1072}," meta ",[1058,3263,1209],{"class":1068},[1058,3265,3266],{"class":1068}," of",[1058,3268,3269],{"class":1072}," handle) ",[1058,3271,1142],{"class":1068},[1058,3273,3274],{"class":1060,"line":1113},[1058,3275,3276],{"class":1166},"  \u002F\u002F blobId    → '9f2c41d0e6a8b37c51f0d2e94ab6c8d1…'  (the eTag)\n",[1058,3278,3279],{"class":1060,"line":1120},[1058,3280,3281],{"class":1166},"  \u002F\u002F recordRef → { collection: 'invoices', id: 'inv-001', slot: 'receipt' }\n",[1058,3283,3284],{"class":1060,"line":1145},[1058,3285,3286],{"class":1166},"  \u002F\u002F bytes     → Uint8Array(48213) — decrypted plaintext\n",[1058,3288,3289],{"class":1060,"line":1170},[1058,3290,3291],{"class":1166},"  \u002F\u002F meta      → { size: 48213, filename: 'receipt-2026-06.pdf',\n",[1058,3293,3294],{"class":1060,"line":1190},[1058,3295,3296],{"class":1166},"  \u002F\u002F               mimeType: 'application\u002Fpdf', createdAt: '2026-07-08T09:30:00.000Z' }\n",[1058,3298,3299],{"class":1060,"line":1206},[1058,3300,3301],{"class":1166},"  \u002F\u002F …write `bytes` to your sink: zip stream, S3 multipart, cold storage\n",[1058,3303,3304],{"class":1060,"line":1215},[1058,3305,2384],{"class":1068},[946,3307,3308,3309,3312,3313,3316,3317,3320],{},"For materializing into a real directory, ",[964,3310,3311],{},"@noy-db\u002Fto-file"," ships\n",[964,3314,3315],{},"exportBlobsToDirectory",", which adds filename sanitization, path-escape containment\n(throws ",[964,3318,3319],{},"PathEscapeError","), and collision handling:",[1049,3322,3324],{"className":1051,"code":3323,"language":1053,"meta":1054,"style":1054},"import { exportBlobsToDirectory } from '@noy-db\u002Fto-file'\n\nconst result = await exportBlobsToDirectory(vault, '.\u002Fout', {\n  filenameProfile: 'macos-smb',   \u002F\u002F the most restrictive default\n  onCollision: 'suffix',          \u002F\u002F 'overwrite' | 'fail' | (existing, attempt) => string\n})\n",[964,3325,3326,3345,3349,3377,3396,3415],{"__ignoreMap":1054},[1058,3327,3328,3330,3332,3335,3337,3339,3341,3343],{"class":1060,"line":1061},[1058,3329,1065],{"class":1064},[1058,3331,1069],{"class":1068},[1058,3333,3334],{"class":1072}," exportBlobsToDirectory",[1058,3336,1076],{"class":1068},[1058,3338,1079],{"class":1064},[1058,3340,1082],{"class":1068},[1058,3342,3311],{"class":1085},[1058,3344,1089],{"class":1068},[1058,3346,3347],{"class":1060,"line":1092},[1058,3348,1117],{"emptyLinePlaceholder":1116},[1058,3350,3351,3353,3355,3357,3359,3361,3364,3366,3368,3371,3373,3375],{"class":1060,"line":1113},[1058,3352,1124],{"class":1123},[1058,3354,2457],{"class":1072},[1058,3356,1130],{"class":1068},[1058,3358,1133],{"class":1064},[1058,3360,3334],{"class":1136},[1058,3362,3363],{"class":1072},"(vault",[1058,3365,1163],{"class":1068},[1058,3367,1082],{"class":1068},[1058,3369,3370],{"class":1085},".\u002Fout",[1058,3372,1160],{"class":1068},[1058,3374,1163],{"class":1068},[1058,3376,1528],{"class":1068},[1058,3378,3379,3382,3384,3386,3389,3391,3393],{"class":1060,"line":1120},[1058,3380,3381],{"class":1148},"  filenameProfile",[1058,3383,1152],{"class":1068},[1058,3385,1082],{"class":1068},[1058,3387,3388],{"class":1085},"macos-smb",[1058,3390,1160],{"class":1068},[1058,3392,1163],{"class":1068},[1058,3394,3395],{"class":1166},"   \u002F\u002F the most restrictive default\n",[1058,3397,3398,3401,3403,3405,3408,3410,3412],{"class":1060,"line":1145},[1058,3399,3400],{"class":1148},"  onCollision",[1058,3402,1152],{"class":1068},[1058,3404,1082],{"class":1068},[1058,3406,3407],{"class":1085},"suffix",[1058,3409,1160],{"class":1068},[1058,3411,1163],{"class":1068},[1058,3413,3414],{"class":1166},"          \u002F\u002F 'overwrite' | 'fail' | (existing, attempt) => string\n",[1058,3416,3417,3419],{"class":1060,"line":1170},[1058,3418,1209],{"class":1068},[1058,3420,1212],{"class":1072},[1049,3422,3424],{"className":1639,"code":3423,"language":141,"meta":1054,"style":1054},"{\n  \"written\": 2,\n  \"bytes\": 96426,\n  \"entries\": [\n    { \"blobId\": \"9f2c41d0e6a8…\", \"path\": \"\u002Fwork\u002Fout\u002Freceipt-2026-06.pdf\" },\n    { \"blobId\": \"4b8e02c7d19f…\", \"path\": \"\u002Fwork\u002Fout\u002Fcontract-signed.pdf\" }\n  ],\n  \"manifestPath\": null\n}\n",[964,3425,3426,3430,3445,3461,3475,3516,3554,3559,3573],{"__ignoreMap":1054},[1058,3427,3428],{"class":1060,"line":1061},[1058,3429,1142],{"class":1068},[1058,3431,3432,3434,3437,3439,3441,3443],{"class":1060,"line":1092},[1058,3433,2254],{"class":1068},[1058,3435,3436],{"class":1123},"written",[1058,3438,1663],{"class":1068},[1058,3440,1152],{"class":1068},[1058,3442,3100],{"class":1727},[1058,3444,1203],{"class":1068},[1058,3446,3447,3449,3452,3454,3456,3459],{"class":1060,"line":1113},[1058,3448,2254],{"class":1068},[1058,3450,3451],{"class":1123},"bytes",[1058,3453,1663],{"class":1068},[1058,3455,1152],{"class":1068},[1058,3457,3458],{"class":1727}," 96426",[1058,3460,1203],{"class":1068},[1058,3462,3463,3465,3468,3470,3472],{"class":1060,"line":1120},[1058,3464,2254],{"class":1068},[1058,3466,3467],{"class":1123},"entries",[1058,3469,1663],{"class":1068},[1058,3471,1152],{"class":1068},[1058,3473,3474],{"class":1068}," [\n",[1058,3476,3477,3480,3482,3485,3487,3489,3491,3494,3496,3498,3500,3503,3505,3507,3509,3512,3514],{"class":1060,"line":1145},[1058,3478,3479],{"class":1068},"    {",[1058,3481,1668],{"class":1068},[1058,3483,3484],{"class":1257},"blobId",[1058,3486,1663],{"class":1068},[1058,3488,1152],{"class":1068},[1058,3490,1668],{"class":1068},[1058,3492,3493],{"class":1085},"9f2c41d0e6a8…",[1058,3495,1663],{"class":1068},[1058,3497,1163],{"class":1068},[1058,3499,1668],{"class":1068},[1058,3501,3502],{"class":1257},"path",[1058,3504,1663],{"class":1068},[1058,3506,1152],{"class":1068},[1058,3508,1668],{"class":1068},[1058,3510,3511],{"class":1085},"\u002Fwork\u002Fout\u002Freceipt-2026-06.pdf",[1058,3513,1663],{"class":1068},[1058,3515,2714],{"class":1068},[1058,3517,3518,3520,3522,3524,3526,3528,3530,3533,3535,3537,3539,3541,3543,3545,3547,3550,3552],{"class":1060,"line":1170},[1058,3519,3479],{"class":1068},[1058,3521,1668],{"class":1068},[1058,3523,3484],{"class":1257},[1058,3525,1663],{"class":1068},[1058,3527,1152],{"class":1068},[1058,3529,1668],{"class":1068},[1058,3531,3532],{"class":1085},"4b8e02c7d19f…",[1058,3534,1663],{"class":1068},[1058,3536,1163],{"class":1068},[1058,3538,1668],{"class":1068},[1058,3540,3502],{"class":1257},[1058,3542,1663],{"class":1068},[1058,3544,1152],{"class":1068},[1058,3546,1668],{"class":1068},[1058,3548,3549],{"class":1085},"\u002Fwork\u002Fout\u002Fcontract-signed.pdf",[1058,3551,1663],{"class":1068},[1058,3553,1292],{"class":1068},[1058,3555,3556],{"class":1060,"line":1190},[1058,3557,3558],{"class":1068},"  ],\n",[1058,3560,3561,3563,3566,3568,3570],{"class":1060,"line":1206},[1058,3562,2254],{"class":1068},[1058,3564,3565],{"class":1123},"manifestPath",[1058,3567,1663],{"class":1068},[1058,3569,1152],{"class":1068},[1058,3571,3572],{"class":1068}," null\n",[1058,3574,3575],{"class":1060,"line":1215},[1058,3576,2384],{"class":1068},[946,3578,3579,3580,3583,3584,3587,3588,3591],{},"The ",[964,3581,3582],{},"'opaque'"," profile renames every file to ",[964,3585,3586],{},"{blobId}.{ext}"," and writes a sidecar\n",[964,3589,3590],{},"manifest.json"," mapping the opaque names back to the originals — useful for handing a\ndirectory to a recipient who should not learn filenames from the listing alone:",[1049,3593,3595],{"className":1051,"code":3594,"language":1053,"meta":1054,"style":1054},"const opaque = await exportBlobsToDirectory(vault, '.\u002Fout', { filenameProfile: 'opaque' })\n\u002F\u002F → opaque.manifestPath === '\u002Fwork\u002Fout\u002Fmanifest.json'\n",[964,3596,3597,3640],{"__ignoreMap":1054},[1058,3598,3599,3601,3604,3606,3608,3610,3612,3614,3616,3618,3620,3622,3624,3627,3629,3631,3634,3636,3638],{"class":1060,"line":1061},[1058,3600,1124],{"class":1123},[1058,3602,3603],{"class":1072}," opaque ",[1058,3605,1130],{"class":1068},[1058,3607,1133],{"class":1064},[1058,3609,3334],{"class":1136},[1058,3611,3363],{"class":1072},[1058,3613,1163],{"class":1068},[1058,3615,1082],{"class":1068},[1058,3617,3370],{"class":1085},[1058,3619,1160],{"class":1068},[1058,3621,1163],{"class":1068},[1058,3623,1069],{"class":1068},[1058,3625,3626],{"class":1148}," filenameProfile",[1058,3628,1152],{"class":1068},[1058,3630,1082],{"class":1068},[1058,3632,3633],{"class":1085},"opaque",[1058,3635,1160],{"class":1068},[1058,3637,1076],{"class":1068},[1058,3639,1212],{"class":1072},[1058,3641,3642],{"class":1060,"line":1092},[1058,3643,3644],{"class":1166},"\u002F\u002F → opaque.manifestPath === '\u002Fwork\u002Fout\u002Fmanifest.json'\n",[1049,3646,3648],{"className":1639,"code":3647,"language":141,"meta":1054,"style":1054},"{\n  \"format\": \"noydb-opaque-export\",\n  \"version\": 1,\n  \"entries\": [\n    {\n      \"opaqueName\": \"9f2c41d0e6a8b37c51f0d2e94ab6c8d1….pdf\",\n      \"originalName\": \"receipt-2026-06.pdf\",\n      \"collection\": \"invoices\",\n      \"recordId\": \"inv-001\",\n      \"slot\": \"receipt\",\n      \"blobId\": \"9f2c41d0e6a8b37c51f0d2e94ab6c8d1…\",\n      \"mimeType\": \"application\u002Fpdf\"\n    }\n  ]\n}\n",[964,3649,3650,3654,3674,3689,3701,3706,3727,3746,3764,3783,3802,3820,3836,3841,3846],{"__ignoreMap":1054},[1058,3651,3652],{"class":1060,"line":1061},[1058,3653,1142],{"class":1068},[1058,3655,3656,3658,3661,3663,3665,3667,3670,3672],{"class":1060,"line":1092},[1058,3657,2254],{"class":1068},[1058,3659,3660],{"class":1123},"format",[1058,3662,1663],{"class":1068},[1058,3664,1152],{"class":1068},[1058,3666,1668],{"class":1068},[1058,3668,3669],{"class":1085},"noydb-opaque-export",[1058,3671,1663],{"class":1068},[1058,3673,1203],{"class":1068},[1058,3675,3676,3678,3681,3683,3685,3687],{"class":1060,"line":1113},[1058,3677,2254],{"class":1068},[1058,3679,3680],{"class":1123},"version",[1058,3682,1663],{"class":1068},[1058,3684,1152],{"class":1068},[1058,3686,2296],{"class":1727},[1058,3688,1203],{"class":1068},[1058,3690,3691,3693,3695,3697,3699],{"class":1060,"line":1120},[1058,3692,2254],{"class":1068},[1058,3694,3467],{"class":1123},[1058,3696,1663],{"class":1068},[1058,3698,1152],{"class":1068},[1058,3700,3474],{"class":1068},[1058,3702,3703],{"class":1060,"line":1145},[1058,3704,3705],{"class":1068},"    {\n",[1058,3707,3708,3711,3714,3716,3718,3720,3723,3725],{"class":1060,"line":1170},[1058,3709,3710],{"class":1068},"      \"",[1058,3712,3713],{"class":1257},"opaqueName",[1058,3715,1663],{"class":1068},[1058,3717,1152],{"class":1068},[1058,3719,1668],{"class":1068},[1058,3721,3722],{"class":1085},"9f2c41d0e6a8b37c51f0d2e94ab6c8d1….pdf",[1058,3724,1663],{"class":1068},[1058,3726,1203],{"class":1068},[1058,3728,3729,3731,3734,3736,3738,3740,3742,3744],{"class":1060,"line":1190},[1058,3730,3710],{"class":1068},[1058,3732,3733],{"class":1257},"originalName",[1058,3735,1663],{"class":1068},[1058,3737,1152],{"class":1068},[1058,3739,1668],{"class":1068},[1058,3741,1559],{"class":1085},[1058,3743,1663],{"class":1068},[1058,3745,1203],{"class":1068},[1058,3747,3748,3750,3752,3754,3756,3758,3760,3762],{"class":1060,"line":1206},[1058,3749,3710],{"class":1068},[1058,3751,1310],{"class":1257},[1058,3753,1663],{"class":1068},[1058,3755,1152],{"class":1068},[1058,3757,1668],{"class":1068},[1058,3759,1326],{"class":1085},[1058,3761,1663],{"class":1068},[1058,3763,1203],{"class":1068},[1058,3765,3766,3768,3771,3773,3775,3777,3779,3781],{"class":1060,"line":1215},[1058,3767,3710],{"class":1068},[1058,3769,3770],{"class":1257},"recordId",[1058,3772,1663],{"class":1068},[1058,3774,1152],{"class":1068},[1058,3776,1668],{"class":1068},[1058,3778,1373],{"class":1085},[1058,3780,1663],{"class":1068},[1058,3782,1203],{"class":1068},[1058,3784,3785,3787,3790,3792,3794,3796,3798,3800],{"class":1060,"line":1246},[1058,3786,3710],{"class":1068},[1058,3788,3789],{"class":1257},"slot",[1058,3791,1663],{"class":1068},[1058,3793,1152],{"class":1068},[1058,3795,1668],{"class":1068},[1058,3797,1516],{"class":1085},[1058,3799,1663],{"class":1068},[1058,3801,1203],{"class":1068},[1058,3803,3804,3806,3808,3810,3812,3814,3816,3818],{"class":1060,"line":1251},[1058,3805,3710],{"class":1068},[1058,3807,3484],{"class":1257},[1058,3809,1663],{"class":1068},[1058,3811,1152],{"class":1068},[1058,3813,1668],{"class":1068},[1058,3815,1690],{"class":1085},[1058,3817,1663],{"class":1068},[1058,3819,1203],{"class":1068},[1058,3821,3822,3824,3826,3828,3830,3832,3834],{"class":1060,"line":1295},[1058,3823,3710],{"class":1068},[1058,3825,1737],{"class":1257},[1058,3827,1663],{"class":1068},[1058,3829,1152],{"class":1068},[1058,3831,1668],{"class":1068},[1058,3833,1540],{"class":1085},[1058,3835,1787],{"class":1068},[1058,3837,3838],{"class":1060,"line":1612},[1058,3839,3840],{"class":1068},"    }\n",[1058,3842,3843],{"class":1060,"line":1617},[1058,3844,3845],{"class":1068},"  ]\n",[1058,3847,3848],{"class":1060,"line":2035},[1058,3849,2384],{"class":1068},[946,3851,3852,3853,3856],{},"The standalone sanitizer lives in ",[964,3854,3855],{},"@noy-db\u002Fhub\u002Futil"," for adopters writing their own\nsinks:",[1049,3858,3860],{"className":1051,"code":3859,"language":1053,"meta":1054,"style":1054},"import { sanitizeFilename } from '@noy-db\u002Fhub\u002Futil'\n\nsanitizeFilename('report: Q2\u002Ffinal?.pdf', { profile: 'windows' })\n\u002F\u002F → 'report_ Q2_final_.pdf'\n\nsanitizeFilename('CON.txt', { profile: 'windows' })\n\u002F\u002F → '_CON.txt'  (Windows reserved device name defused)\n\nsanitizeFilename('scan-'.repeat(80) + '.pdf', { profile: 'posix', maxBytes: 240 })\n\u002F\u002F → 'scan-scan-…' truncated to 240 bytes on a code-point boundary — headroom for '-1', '-2', … suffixes\n",[964,3861,3862,3881,3885,3919,3924,3928,3959,3964,3968,4032],{"__ignoreMap":1054},[1058,3863,3864,3866,3868,3871,3873,3875,3877,3879],{"class":1060,"line":1061},[1058,3865,1065],{"class":1064},[1058,3867,1069],{"class":1068},[1058,3869,3870],{"class":1072}," sanitizeFilename",[1058,3872,1076],{"class":1068},[1058,3874,1079],{"class":1064},[1058,3876,1082],{"class":1068},[1058,3878,3855],{"class":1085},[1058,3880,1089],{"class":1068},[1058,3882,3883],{"class":1060,"line":1092},[1058,3884,1117],{"emptyLinePlaceholder":1116},[1058,3886,3887,3890,3892,3894,3897,3899,3901,3903,3906,3908,3910,3913,3915,3917],{"class":1060,"line":1113},[1058,3888,3889],{"class":1136},"sanitizeFilename",[1058,3891,1139],{"class":1072},[1058,3893,1160],{"class":1068},[1058,3895,3896],{"class":1085},"report: Q2\u002Ffinal?.pdf",[1058,3898,1160],{"class":1068},[1058,3900,1163],{"class":1068},[1058,3902,1069],{"class":1068},[1058,3904,3905],{"class":1148}," profile",[1058,3907,1152],{"class":1068},[1058,3909,1082],{"class":1068},[1058,3911,3912],{"class":1085},"windows",[1058,3914,1160],{"class":1068},[1058,3916,1076],{"class":1068},[1058,3918,1212],{"class":1072},[1058,3920,3921],{"class":1060,"line":1120},[1058,3922,3923],{"class":1166},"\u002F\u002F → 'report_ Q2_final_.pdf'\n",[1058,3925,3926],{"class":1060,"line":1145},[1058,3927,1117],{"emptyLinePlaceholder":1116},[1058,3929,3930,3932,3934,3936,3939,3941,3943,3945,3947,3949,3951,3953,3955,3957],{"class":1060,"line":1170},[1058,3931,3889],{"class":1136},[1058,3933,1139],{"class":1072},[1058,3935,1160],{"class":1068},[1058,3937,3938],{"class":1085},"CON.txt",[1058,3940,1160],{"class":1068},[1058,3942,1163],{"class":1068},[1058,3944,1069],{"class":1068},[1058,3946,3905],{"class":1148},[1058,3948,1152],{"class":1068},[1058,3950,1082],{"class":1068},[1058,3952,3912],{"class":1085},[1058,3954,1160],{"class":1068},[1058,3956,1076],{"class":1068},[1058,3958,1212],{"class":1072},[1058,3960,3961],{"class":1060,"line":1190},[1058,3962,3963],{"class":1166},"\u002F\u002F → '_CON.txt'  (Windows reserved device name defused)\n",[1058,3965,3966],{"class":1060,"line":1206},[1058,3967,1117],{"emptyLinePlaceholder":1116},[1058,3969,3970,3972,3974,3976,3979,3981,3983,3986,3988,3991,3993,3996,3998,4001,4003,4005,4007,4009,4011,4013,4016,4018,4020,4023,4025,4028,4030],{"class":1060,"line":1215},[1058,3971,3889],{"class":1136},[1058,3973,1139],{"class":1072},[1058,3975,1160],{"class":1068},[1058,3977,3978],{"class":1085},"scan-",[1058,3980,1160],{"class":1068},[1058,3982,1043],{"class":1068},[1058,3984,3985],{"class":1136},"repeat",[1058,3987,1139],{"class":1072},[1058,3989,3990],{"class":1727},"80",[1058,3992,2391],{"class":1072},[1058,3994,3995],{"class":1068},"+",[1058,3997,1082],{"class":1068},[1058,3999,4000],{"class":1085},".pdf",[1058,4002,1160],{"class":1068},[1058,4004,1163],{"class":1068},[1058,4006,1069],{"class":1068},[1058,4008,3905],{"class":1148},[1058,4010,1152],{"class":1068},[1058,4012,1082],{"class":1068},[1058,4014,4015],{"class":1085},"posix",[1058,4017,1160],{"class":1068},[1058,4019,1163],{"class":1068},[1058,4021,4022],{"class":1148}," maxBytes",[1058,4024,1152],{"class":1068},[1058,4026,4027],{"class":1727}," 240",[1058,4029,1076],{"class":1068},[1058,4031,1212],{"class":1072},[1058,4033,4034],{"class":1060,"line":1246},[1058,4035,4036],{"class":1166},"\u002F\u002F → 'scan-scan-…' truncated to 240 bytes on a code-point boundary — headroom for '-1', '-2', … suffixes\n",[941,4038,4040],{"id":4039},"api-reference","API reference",[1336,4042,4044,4046,4047],{"id":4043},"blobset-from-collectionblobid",[964,4045,1347],{}," — from ",[964,4048,1021],{},[4050,4051,4052,4068],"table",{},[4053,4054,4055],"thead",{},[4056,4057,4058,4062,4065],"tr",{},[4059,4060,4061],"th",{},"Method",[4059,4063,4064],{},"Returns",[4059,4066,4067],{},"Purpose",[4069,4070,4071,4087,4105,4136,4150,4185,4207,4221,4235,4261,4275,4293,4332,4359,4378],"tbody",{},[4056,4072,4073,4079,4084],{},[4074,4075,4076],"td",{},[964,4077,4078],{},"put(slotName, data, opts?)",[4074,4080,4081],{},[964,4082,4083],{},"void",[4074,4085,4086],{},"Upload bytes to a named slot. Dedups by keyed eTag; overwriting a slot releases the old content's reference.",[4056,4088,4089,4094,4099],{},[4074,4090,4091],{},[964,4092,4093],{},"get(slotName)",[4074,4095,4096],{},[964,4097,4098],{},"Uint8Array | null",[4074,4100,4101,4102,4104],{},"Fetch and decrypt all bytes. ",[964,4103,2066],{}," for a missing slot.",[4056,4106,4107,4111,4116],{},[4074,4108,4109],{},[964,4110,2813],{},[4074,4112,4113],{},[964,4114,4115],{},"SlotInfo[]",[4074,4117,4118,4119,967,4121,967,4123,967,4125,967,4127,967,4130,967,4132,4135],{},"All slot entries (",[964,4120,1660],{},[964,4122,1681],{},[964,4124,1701],{},[964,4126,1720],{},[964,4128,4129],{},"mimeType?",[964,4131,1756],{},[964,4133,4134],{},"uploadedBy?","). Metadata only — no chunk reads.",[4056,4137,4138,4143,4147],{},[4074,4139,4140],{},[964,4141,4142],{},"delete(slotName)",[4074,4144,4145],{},[964,4146,4083],{},[4074,4148,4149],{},"Remove the slot and decrement the blob's reference count.",[4056,4151,4152,4157,4162],{},[4074,4153,4154],{},[964,4155,4156],{},"response(slotName, opts?)",[4074,4158,4159],{},[964,4160,4161],{},"Response | null",[4074,4163,4164,4165,4168,4169,967,4172,967,4175,967,4178,967,4181,4184],{},"Native ",[964,4166,4167],{},"Response"," with ",[964,4170,4171],{},"Content-Type",[964,4173,4174],{},"Content-Length",[964,4176,4177],{},"Content-Disposition",[964,4179,4180],{},"ETag",[964,4182,4183],{},"Last-Modified"," headers.",[4056,4186,4187,4192,4197],{},[4074,4188,4189],{},[964,4190,4191],{},"objectURL(slotName, opts?)",[4074,4193,4194],{},[964,4195,4196],{},"{ url, revoke } | null",[4074,4198,4199,4200,4203,4204,1043],{},"Decrypt and wrap in a browser ObjectURL. ",[964,4201,4202],{},"opts.mimeType"," overrides the stored type. Caller must call ",[964,4205,4206],{},"revoke()",[4056,4208,4209,4214,4218],{},[4074,4210,4211],{},[964,4212,4213],{},"publish(slotName, label)",[4074,4215,4216],{},[964,4217,4083],{},[4074,4219,4220],{},"Snapshot the current slot content as a named version. The version holds its own reference — the bytes survive later slot overwrites\u002Fdeletes.",[4056,4222,4223,4228,4232],{},[4074,4224,4225],{},[964,4226,4227],{},"getVersion(slotName, label)",[4074,4229,4230],{},[964,4231,4098],{},[4074,4233,4234],{},"Fetch a published version's bytes.",[4056,4236,4237,4242,4247],{},[4074,4238,4239],{},[964,4240,4241],{},"listVersions(slotName)",[4074,4243,4244],{},[964,4245,4246],{},"VersionRecord[]",[4074,4248,4249,4250,967,4253,967,4255,967,4258,977],{},"All published versions (",[964,4251,4252],{},"label",[964,4254,1681],{},[964,4256,4257],{},"publishedAt",[964,4259,4260],{},"publishedBy?",[4056,4262,4263,4268,4272],{},[4074,4264,4265],{},[964,4266,4267],{},"deleteVersion(slotName, label)",[4074,4269,4270],{},[964,4271,4083],{},[4074,4273,4274],{},"Delete a published version and release its reference.",[4056,4276,4277,4282,4286],{},[4074,4278,4279],{},[964,4280,4281],{},"responseVersion(slotName, label, opts?)",[4074,4283,4284],{},[964,4285,4161],{},[4074,4287,4288,4289,4292],{},"Like ",[964,4290,4291],{},"response()"," but reads the published version.",[4056,4294,4295,4300,4305],{},[4074,4296,4297],{},[964,4298,4299],{},"blobInfo(slotName)",[4074,4301,4302],{},[964,4303,4304],{},"BlobObject | null",[4074,4306,4307,4308,967,4310,967,4312,967,4315,967,4318,967,4321,967,4324,967,4326,967,4329,1043],{},"Content metadata: ",[964,4309,1681],{},[964,4311,1720],{},[964,4313,4314],{},"compressedSize",[964,4316,4317],{},"compression",[964,4319,4320],{},"chunkSize",[964,4322,4323],{},"chunkCount",[964,4325,4129],{},[964,4327,4328],{},"createdAt",[964,4330,4331],{},"refCount",[4056,4333,4334,4339,4344],{},[4074,4335,4336],{},[964,4337,4338],{},"atTier()",[4074,4340,4341],{},[964,4342,4343],{},"Promise\u003CBlobSet>",[4074,4345,4346,4347,4349,4350,4352,4353,4355,4356,4358],{},"Cleared-read path to an ",[950,4348,2820],{}," record's blobs (#749). Runs the tier-access check, then returns a ",[964,4351,1347],{}," that reads through the tier gate; ",[964,4354,2844],{}," for an ungranted caller. Plain ",[964,4357,2806],{}," treats an elevated record's blobs as nonexistent.",[4056,4360,4361,4366,4371],{},[4074,4362,4363],{},[964,4364,4365],{},"presignedUrl(slotName, expiresInSeconds?)",[4074,4367,4368],{},[964,4369,4370],{},"string | null",[4074,4372,4373,4374,4377],{},"Presigned URL to the ",[950,4375,4376],{},"ciphertext"," of a single-chunk blob, on stores that support presigning. Default expiry 3600 s.",[4056,4379,4380,4385,4389],{},[4074,4381,4382],{},[964,4383,4384],{},"decryptResponse(slotName, cipherResponse)",[4074,4386,4387],{},[964,4388,4161],{},[4074,4390,4391,4392,4394,4395,1043],{},"Decrypt a ciphertext ",[964,4393,4167],{}," (e.g. fetched from a presigned URL) into a plaintext ",[964,4396,4167],{},[946,4398,4399,4400,2405,4403,4406,4407,4410,4411,1203,4414,967,4417,967,4420,4423],{},"The subpath also exports the MIME helpers ",[964,4401,4402],{},"detectMimeType",[964,4404,4405],{},"detectMagic"," \u002F\n",[964,4408,4409],{},"isPreCompressed"," and the internal-collection constants (",[964,4412,4413],{},"BLOB_COLLECTION",[964,4415,4416],{},"BLOB_INDEX_COLLECTION",[964,4418,4419],{},"BLOB_CHUNKS_COLLECTION",[964,4421,4422],{},"DEFAULT_CHUNK_SIZE",", …).",[1336,4425,4427],{"id":4426},"blobputoptions",[964,4428,4429],{},"BlobPutOptions",[4050,4431,4432,4447],{},[4053,4433,4434],{},[4056,4435,4436,4439,4442,4445],{},[4059,4437,4438],{},"Option",[4059,4440,4441],{},"Type",[4059,4443,4444],{},"Default",[4059,4446,4067],{},[4069,4448,4449,4466,4486,4511,4527],{},[4056,4450,4451,4455,4460,4463],{},[4074,4452,4453],{},[964,4454,1737],{},[4074,4456,4457],{},[964,4458,4459],{},"string",[4074,4461,4462],{},"auto-detected from magic bytes",[4074,4464,4465],{},"MIME type hint stored on the slot.",[4056,4467,4468,4472,4477,4483],{},[4074,4469,4470],{},[964,4471,4320],{},[4074,4473,4474],{},[964,4475,4476],{},"number",[4074,4478,4479,4482],{},[964,4480,4481],{},"store.maxBlobBytes",", else 256 KB",[4074,4484,4485],{},"Raw bytes per chunk. Explicit value wins over the store's advertised cap.",[4056,4487,4488,4493,4498,4508],{},[4074,4489,4490],{},[964,4491,4492],{},"compress",[4074,4494,4495],{},[964,4496,4497],{},"boolean",[4074,4499,4500,4503,4504,4507],{},[964,4501,4502],{},"true","; auto-",[964,4505,4506],{},"false"," for pre-compressed MIME types (JPEG, PNG, ZIP, …)",[4074,4509,4510],{},"Gzip before encrypting.",[4056,4512,4513,4517,4521,4524],{},[4074,4514,4515],{},[964,4516,1776],{},[4074,4518,4519],{},[964,4520,4459],{},[4074,4522,4523],{},"the session user",[4074,4525,4526],{},"User id recorded on the slot.",[4056,4528,4529,4533,4537,4540],{},[4074,4530,4531],{},[964,4532,1701],{},[4074,4534,4535],{},[964,4536,4459],{},[4074,4538,4539],{},"the slot name",[4074,4541,4542],{},"User-visible display\u002Fdownload name.",[1336,4544,4546],{"id":4545},"blobresponseoptions",[964,4547,4548],{},"BlobResponseOptions",[4050,4550,4551,4563],{},[4053,4552,4553],{},[4056,4554,4555,4557,4559,4561],{},[4059,4556,4438],{},[4059,4558,4441],{},[4059,4560,4444],{},[4059,4562,4067],{},[4069,4564,4565,4595],{},[4056,4566,4567,4572,4576,4580],{},[4074,4568,4569],{},[964,4570,4571],{},"inline",[4074,4573,4574],{},[964,4575,4497],{},[4074,4577,4578],{},[964,4579,4506],{},[4074,4581,4582,4584,4585,4588,4589,4584,4591,4594],{},[964,4583,4502],{}," → ",[964,4586,4587],{},"Content-Disposition: inline"," (render in tab); ",[964,4590,4506],{},[964,4592,4593],{},"attachment"," (download).",[4056,4596,4597,4601,4605,4608],{},[4074,4598,4599],{},[964,4600,1701],{},[4074,4602,4603],{},[964,4604,4459],{},[4074,4606,4607],{},"the slot's stored filename",[4074,4609,4610,4611,4613],{},"Override the filename in the ",[964,4612,4177],{}," header.",[1336,4615,4617,4619],{"id":4616},"blobfields-policy",[964,4618,2077],{}," policy",[946,4621,4622,4623,1043],{},"Declared per collection: ",[964,4624,4625],{},"vault.collection(name, { blobFields: { [slotName]: policy } })",[4050,4627,4628,4639],{},[4053,4629,4630],{},[4056,4631,4632,4635,4637],{},[4059,4633,4634],{},"Key",[4059,4636,4441],{},[4059,4638,4067],{},[4069,4640,4641,4657,4679,4695,4713,4735,4753],{},[4056,4642,4643,4648,4652],{},[4074,4644,4645],{},[964,4646,4647],{},"retainDays",[4074,4649,4650],{},[964,4651,4476],{},[4074,4653,4654,4655,1043],{},"Age-based TTL — a slot uploaded more than N days ago evicts on the next ",[964,4656,2081],{},[4056,4658,4659,4664,4669],{},[4074,4660,4661],{},[964,4662,4663],{},"evictWhen",[4074,4665,4666],{},[964,4667,4668],{},"(record) => boolean",[4074,4670,4671,4672,4674,4675,4678],{},"Evict when the predicate over the decrypted record returns ",[964,4673,4502],{},". A throwing predicate does ",[950,4676,4677],{},"not"," evict (fail-closed).",[4056,4680,4681,4685,4689],{},[4074,4682,4683],{},[964,4684,2418],{},[4074,4686,4687],{},[964,4688,4668],{},[4074,4690,4691,4692,4694],{},"While ",[964,4693,4502],{},", the slot is never evicted, overriding both triggers. A throwing predicate holds the slot.",[4056,4696,4697,4701,4706],{},[4074,4698,4699],{},[964,4700,2422],{},[4074,4702,4703],{},[964,4704,4705],{},"(record) => Date | string | number | null",[4074,4707,4708,4709,4712],{},"Retention floor — no eviction while ",[964,4710,4711],{},"now \u003C retainUntil",". Unparseable or throwing values hold the slot.",[4056,4714,4715,4720,4724],{},[4074,4716,4717],{},[964,4718,4719],{},"external",[4074,4721,4722],{},[964,4723,4497],{},[4074,4725,4726,4727,4730,4731,4734],{},"Store this field's bytes as a single raw ",[950,4728,4729],{},"unencrypted"," object in the vault's object projection (",[964,4732,4733],{},"createNoydb({ objectStore })",") — servable from S3\u002FCDN, outside the zero-knowledge guarantee. The encrypted slot record remains the catalog entry.",[4056,4736,4737,4741,4745],{},[4074,4738,4739],{},[964,4740,12],{},[4074,4742,4743],{},[964,4744,4497],{},[4074,4746,4747,4748,4750,4751,1043],{},"For ",[964,4749,4719],{}," fields: world-readable object instead of presigned-only. Default ",[964,4752,4506],{},[4056,4754,4755,4760,4765],{},[4074,4756,4757],{},[964,4758,4759],{},"backlink",[4074,4761,4762],{},[964,4763,4764],{},"'opaque-token' | 'encrypted' | 'plain' | 'none'",[4074,4766,4747,4767,4769,4770,4773],{},[964,4768,4719],{}," fields: how to stamp a reference back to the record on the object's metadata. Default ",[964,4771,4772],{},"'opaque-token'"," (no name leak).",[946,4775,4776,4779,4780,4783,4784,962,4787,967,4789,967,4791,967,4793,967,4795,1203,4797,977],{},[964,4777,4778],{},"vault.compact(options?)"," accepts ",[964,4781,4782],{},"{ now?, maxEvictions?, dryRun? }"," and returns a\n",[964,4785,4786],{},"CompactionResult",[964,4788,2257],{},[964,4790,2273],{},[964,4792,2289],{},[964,4794,2305],{},[964,4796,2321],{},[964,4798,2337],{},[1336,4800,4802],{"id":4801},"vaultexportblobsoptions",[964,4803,3180],{},[946,4805,4806,4807,1014,4810,4813,4814,4817,4818,4821,4822,1043],{},"Returns an ",[964,4808,4809],{},"ExportBlobsHandle",[964,4811,4812],{},"AsyncIterable\u003CExportedBlob>"," plus ",[964,4815,4816],{},"abort()"," and a\nreadonly ",[964,4819,4820],{},"aborted"," flag. Requires the caller's keyring to grant plaintext blob export;\naborting makes the next iteration throw ",[964,4823,4824],{},"ExportBlobsAbortedError",[4050,4826,4827,4837],{},[4053,4828,4829],{},[4056,4830,4831,4833,4835],{},[4059,4832,4438],{},[4059,4834,4441],{},[4059,4836,4067],{},[4069,4838,4839,4853,4868,4885],{},[4056,4840,4841,4845,4850],{},[4074,4842,4843],{},[964,4844,2289],{},[4074,4846,4847],{},[964,4848,4849],{},"readonly string[]",[4074,4851,4852],{},"Allowlist. Omit to export from every collection the caller can read.",[4056,4854,4855,4860,4865],{},[4074,4856,4857],{},[964,4858,4859],{},"where",[4074,4861,4862],{},[964,4863,4864],{},"(record, { collection, id }) => boolean",[4074,4866,4867],{},"Per-record predicate, evaluated before any of that record's chunks are read.",[4056,4869,4870,4875,4879],{},[4074,4871,4872],{},[964,4873,4874],{},"afterBlobId",[4074,4876,4877],{},[964,4878,4459],{},[4074,4880,4881,4882,4884],{},"Resume cursor — skip tuples up to and including this ",[964,4883,3484],{},", for idempotent batch re-runs.",[4056,4886,4887,4892,4897],{},[4074,4888,4889],{},[964,4890,4891],{},"signal",[4074,4893,4894],{},[964,4895,4896],{},"AbortSignal",[4074,4898,4899,4900,1043],{},"External abort, honored alongside ",[964,4901,4902],{},"handle.abort()",[1336,4904,4906],{"id":4905},"exportblobstodirectoryvault-targetdir-options",[964,4907,4908],{},"exportBlobsToDirectory(vault, targetDir, options?)",[946,4910,4911,4912,4915,4916,4918,4919,4921,4922,4924,4925,4927],{},"Returns ",[964,4913,4914],{},"{ written, bytes, entries, manifestPath }","; ",[964,4917,3565],{}," is the absolute\npath of ",[964,4920,3590],{}," for the ",[964,4923,3582],{}," profile, ",[964,4926,2066],{}," otherwise.",[4050,4929,4930,4942],{},[4053,4931,4932],{},[4056,4933,4934,4936,4938,4940],{},[4059,4935,4438],{},[4059,4937,4441],{},[4059,4939,4444],{},[4059,4941,4067],{},[4069,4943,4944,4964,4984],{},[4056,4945,4946,4951,4956,4961],{},[4074,4947,4948],{},[964,4949,4950],{},"filenameProfile",[4074,4952,4953],{},[964,4954,4955],{},"FilenameProfile",[4074,4957,4958],{},[964,4959,4960],{},"'macos-smb'",[4074,4962,4963],{},"Sanitization target profile (most restrictive common default).",[4056,4965,4966,4971,4976,4981],{},[4074,4967,4968],{},[964,4969,4970],{},"onCollision",[4074,4972,4973],{},[964,4974,4975],{},"'suffix' | 'overwrite' | 'fail' | (existing, attempt) => string",[4074,4977,4978],{},[964,4979,4980],{},"'suffix'",[4074,4982,4983],{},"How to resolve two blobs sanitizing to the same name.",[4056,4985,4986,4996,4999,5001],{},[4074,4987,4988,2405,4990,2405,4992,2405,4994],{},[964,4989,2289],{},[964,4991,4859],{},[964,4993,4874],{},[964,4995,4891],{},[4074,4997,4998],{},"—",[4074,5000,4998],{},[4074,5002,5003,5004,1043],{},"Forwarded to ",[964,5005,5006],{},"vault.exportBlobs",[1336,5008,5010],{"id":5009},"sanitizefilenamename-options",[964,5011,5012],{},"sanitizeFilename(name, options)",[946,5014,5015,5016,5019,5020,5023,5024,5027],{},"Pure string in \u002F string out; throws ",[964,5017,5018],{},"FilenameSanitizationError"," when the input cannot\nbe made safe (NUL byte, ",[964,5021,5022],{},".."," traversal segment, empty after normalization, missing\n",[964,5025,5026],{},"opaqueId"," for the opaque profile).",[4050,5029,5030,5040],{},[4053,5031,5032],{},[4056,5033,5034,5036,5038],{},[4059,5035,4438],{},[4059,5037,4441],{},[4059,5039,4067],{},[4069,5041,5042,5057,5088],{},[4056,5043,5044,5049,5054],{},[4074,5045,5046],{},[964,5047,5048],{},"profile",[4074,5050,5051],{},[964,5052,5053],{},"'posix' | 'windows' | 'macos-smb' | 'zip' | 'url-path' | 's3-key' | 'opaque'",[4074,5055,5056],{},"Storage-destination profile to defang for.",[4056,5058,5059,5064,5068],{},[4074,5060,5061],{},[964,5062,5063],{},"maxBytes",[4074,5065,5066],{},[964,5067,4476],{},[4074,5069,5070,5071,2831,5073,2831,5075,5077,5078,5080,5081,2831,5084,5087],{},"Override the per-profile length cap (255 for ",[964,5072,4015],{},[964,5074,3912],{},[964,5076,165],{},", 240 for ",[964,5079,3388],{},", 1024 for ",[964,5082,5083],{},"url-path",[964,5085,5086],{},"s3-key",") — e.g. leave headroom for collision suffixes.",[4056,5089,5090,5094,5098],{},[4074,5091,5092],{},[964,5093,5026],{},[4074,5095,5096],{},[964,5097,4459],{},[4074,5099,5100,5101,5103,5104,5107],{},"Required for ",[964,5102,3582],{},": the output becomes ",[964,5105,5106],{},"{opaqueId}.{ext}"," (extension kept only if alphanumeric and ≤ 16 bytes).",[946,5109,5110,5111,5114],{},"Always-on transforms across all profiles: NFC normalization, bidi-override stripping\n(defeats ",[964,5112,5113],{},"‮","-style extension spoofing), NUL rejection (hard fail — silent stripping\nwould enable truncation bypass), and trimming of leading\u002Ftrailing whitespace and\ncontrol characters.",[941,5116,5118],{"id":5117},"behavior-when-not-opted-in","Behavior when NOT opted in",[1006,5120,5121,5133,5136],{},[1009,5122,5123,5125,5126,5129,5130,5132],{},[964,5124,1021],{}," throws an error pointing you at\n",[964,5127,5128],{},"createNoydb({ blobsStrategy: withBlobs() })"," and the ",[964,5131,1108],{}," import.",[1009,5134,5135],{},"All blob machinery stays out of the bundle — ~2,376 LOC saved.",[1009,5137,5138,5140,5141,5143],{},[964,5139,2081],{}," with no ",[964,5142,2077],{}," declared anywhere is a no-op returning zeros.",[941,5145,5147],{"id":5146},"limits-gotchas","Limits & gotchas",[1006,5149,5150,5158,5172,5189,5199,5213,5226,5234,5269,5297],{},[1009,5151,5152,5157],{},[950,5153,5154,5156],{},[964,5155,4291],{}," is buffered",", not truly streaming — all chunks are loaded into memory\nbefore the body is enqueued. Budget accordingly for very large files.",[1009,5159,5160,5165,5166,5168,5169,5171],{},[950,5161,5162,5164],{},[964,5163,2050],{}," is browser-only"," — it throws where ",[964,5167,2054],{}," is missing —\nand the caller owns ",[964,5170,4206],{},"; an unrevoked URL pins the decrypted bytes for the\nlifetime of the document.",[1009,5173,5174,5177,5178,5180,5181,5184,5185,5188],{},[950,5175,5176],{},"Chunk size resolution",": explicit ",[964,5179,4320],{}," on ",[964,5182,5183],{},"put()"," > the store's advertised\n",[964,5186,5187],{},"maxBlobBytes"," (e.g. 256 KB for DynamoDB-backed stores) > the 256 KB default.",[1009,5190,5191,5194,5195,5198],{},[950,5192,5193],{},"Mutating a slot publishes new content"," — blobs are content-addressed and immutable;\noverwriting a slot points it at a new eTag and releases the old one. Use\n",[964,5196,5197],{},"publish(slot, label)"," to pin a version that survives later overwrites.",[1009,5200,5201,5204,5205,5207,5208,2831,5210,5212],{},[950,5202,5203],{},"Compaction is consumer-scheduled"," — no background daemon. Policy predicates are\nfail-closed: a throwing ",[964,5206,4663],{}," never evicts, a throwing ",[964,5209,2418],{},[964,5211,2422],{},"\nholds the slot.",[1009,5214,5215,5221,5222,5225],{},[950,5216,5217,5220],{},[964,5218,5219],{},"presignedUrl()"," serves ciphertext",", works only for single-chunk blobs on stores\nthat support presigning, and must be paired with ",[964,5223,5224],{},"decryptResponse()"," (or a service\nworker) client-side.",[1009,5227,5228,5233],{},[950,5229,5230,5232],{},[964,5231,4719],{}," blob fields are unencrypted by design"," — they exist to serve assets\ndirectly from S3\u002FCDN and sit outside the zero-knowledge guarantee. Keep sensitive\nattachments on the default encrypted-chunk path.",[1009,5235,5236,5246,5247,5249,5250,5252,5253,4915,5255,5258,5259,5261,5262,5264,5265,1043],{},[950,5237,5238,5239,5241,5242,5245],{},"Tiered blobs need ",[964,5240,2904],{},", and ",[964,5243,5244],{},"blobTierPolicy: 'dedup'"," keeps shared content\nunder the flat DEK."," A ",[964,5248,2077],{}," + ",[964,5251,872],{}," collection must set ",[964,5254,2904],{},[964,5256,5257],{},"dedup","\npolicy hides a shared blob from tier-0 callers at the read gate but leaves its chunks\ndecryptable at rest under the flat ",[964,5260,2790],{}," DEK. Use ",[964,5263,2876],{}," (the default) when at-rest\nisolation of shared content matters. See ",[955,5266,5268],{"href":5267},"#tiered-blobs-content-follows-the-records-tier","Tiered blobs",[1009,5270,5271,5277,5278,5281,5282,5285,5286,5288,5289,5292,5293,5296],{},[950,5272,5273,5274,5276],{},"A ",[964,5275,2077],{}," slot is not queryable."," Since ",[964,5279,5280],{},"0.3.0-pre.9",", a\ndeclared blob field carries an enforced ",[964,5283,5284],{},"queryable: 'none'"," posture (see\n",[955,5287,896],{"href":897},"): ",[964,5290,5291],{},"query().where()"," on it throws ",[964,5294,5295],{},"FieldNotQueryableError"," instead of\nsilently matching nothing. Query record metadata, not blob slots.",[1009,5298,5299,5304,5305,5307,5308,5310,5311,5314,5315,5320],{},[950,5300,5301,5303],{},[964,5302,1031],{}," shreds blobs on every collection by default"," — not only collections that\ndeclared ",[964,5306,2077],{},". A collection that only ever wrote blobs via ",[964,5309,2505],{}," still has\nthem crypto-shredded on erasure. Opt into ",[964,5312,5313],{},"scopedPurge: true"," (see\n",[955,5316,2431,5318],{"href":5317},"#erasure-blobs-shred-with-forget",[964,5319,1031],{},") to scan only\ndeclared collections; undeclared ones are then skipped and reported, never silently.",[941,5322,5324],{"id":5323},"see-also","See also",[1006,5326,5327,5332,5340,5345,5350,5359,5367,5375,5383,5392],{},[1009,5328,5329,5331],{},[955,5330,507],{"href":508}," — invoices with attached receipt scans,\nretention, and export in one recipe",[1009,5333,5334,1014,5336,5339],{},[955,5335,629],{"href":630},[964,5337,5338],{},".noydb"," containers carry blobs alongside records",[1009,5341,5342,5344],{},[955,5343,697],{"href":698}," — slot metadata is itself versioned envelope data",[1009,5346,5347,5349],{},[955,5348,808],{"href":809}," — send blob chunks to a separate backend (S3 \u002F R2) while\nrecord metadata stays on the primary store",[1009,5351,5352,5354,5355,5358],{},[955,5353,812],{"href":813}," — the sibling heavy-field strategy for large\n",[993,5356,5357],{},"structured\u002Ftext"," fields that still need schema validation and query",[1009,5360,5361,5363,5364,5366],{},[955,5362,896],{"href":897}," — the field-feature posture a ",[964,5365,2077],{}," declaration carries",[1009,5368,5369,5371,5372,5374],{},[955,5370,685],{"href":686}," — right-to-erasure crypto-shredding; how attached blobs shred with a record and the ",[964,5373,2519],{}," scan-scoping knob",[1009,5376,5377,5380,5381],{},[955,5378,5379],{"href":51},"Stores"," · ",[955,5382,21],{"href":66},[1009,5384,5385,5380,5388],{},[955,5386,5387],{"href":598},"Services overview",[955,5389,5391],{"href":5390},"\u002Forientation","Orientation map",[1009,5393,5394,5395,1043],{},"Proven by showcase ",[955,5396,5400],{"href":5397,"rel":5398},"https:\u002F\u002Fgithub.com\u002Fnoy-db\u002Fdocs\u002Fblob\u002Fmain\u002Fshowcases\u002Fsrc\u002F08-with-blobs.showcase.test.ts",[5399],"nofollow",[964,5401,5402],{},"08-with-blobs",[5404,5405,5406],"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 .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 .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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .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}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}",{"title":1054,"searchDepth":1113,"depth":1113,"links":5408},[5409,5410,5411,5412,5424,5435,5436,5437],{"id":943,"depth":1092,"text":944},{"id":1003,"depth":1092,"text":1004},{"id":1046,"depth":1092,"text":1047},{"id":1333,"depth":1092,"text":1334,"children":5413},[5414,5415,5416,5417,5422,5423],{"id":1338,"depth":1113,"text":1339},{"id":1847,"depth":1113,"text":1848},{"id":2070,"depth":1113,"text":2071},{"id":2430,"depth":1113,"text":5418,"children":5419},"Erasure — blobs shred with forget()",[5420],{"id":2515,"depth":1120,"text":5421},"Scoping the scan with scopedPurge",{"id":2759,"depth":1113,"text":2760},{"id":3174,"depth":1113,"text":3175},{"id":4039,"depth":1092,"text":4040,"children":5425},[5426,5428,5429,5430,5432,5433,5434],{"id":4043,"depth":1113,"text":5427},"BlobSet — from collection.blob(id)",{"id":4426,"depth":1113,"text":4429},{"id":4545,"depth":1113,"text":4548},{"id":4616,"depth":1113,"text":5431},"blobFields policy",{"id":4801,"depth":1113,"text":3180},{"id":4905,"depth":1113,"text":4908},{"id":5009,"depth":1113,"text":5012},{"id":5117,"depth":1092,"text":5118},{"id":5146,"depth":1092,"text":5147},{"id":5323,"depth":1092,"text":5324},null,"Encrypted binary attachments — chunked AES-256-GCM storage with content-addressed dedup, MIME sniffing, retention compaction, and bulk export.","md",{},"service",{"title":621,"description":5439},"stable","important","BOqC8zdANiIkr9I-P9v49BIqnHWURQNe2Hn-Zqqrjms",{"data":5448,"body":5449},{},{"type":5450,"children":5451},"root",[5452],{"type":5453,"tag":946,"props":5454,"children":5455},"element",{},[5456],{"type":5453,"tag":964,"props":5457,"children":5459},{"className":5458},[],[5460],{"type":5461,"value":5462},"text","with-shape",{"data":5464,"body":5465},{},{"type":5450,"children":5466},[5467],{"type":5453,"tag":946,"props":5468,"children":5469},{},[5470],{"type":5453,"tag":964,"props":5471,"children":5473},{"className":5472},[],[5474],{"type":5461,"value":1108},{"data":5476,"body":5477},{},{"type":5450,"children":5478},[5479],{"type":5453,"tag":946,"props":5480,"children":5481},{},[5482],{"type":5453,"tag":964,"props":5483,"children":5485},{"className":5484},[],[5486],{"type":5461,"value":1017},1791896586583]