{"_id":"@12-apps/pwa","_rev":"19-8aac7d84f2cebaa1218eb33abe143a27","name":"@12-apps/pwa","dist-tags":{"latest":"2.6.2"},"versions":{"1.0.0":{"name":"@12-apps/pwa","version":"1.0.0","license":"MIT","_id":"@12-apps/pwa@1.0.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"2df53abee8adf0ee721e06b9536fb91f08b69697","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.0.0.tgz","fileCount":8,"integrity":"sha512-arvmMuvtr0Z+8j3L061Xp8f633Cbz/SCzu47SqXt93zfaBy0IsTvdHiJOLfVoDde3lK5jT8W/vsSXfOioO+e1w==","signatures":[{"sig":"MEYCIQCdfHo7AhNdvspk6/2c3pxWLk6XQlX9cUwui1phqpU9jQIhAOscV3KxKZN7fau9uX5SgyaNGPGtQVeZvZv6KwJnnciv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"f9c9457f43bc8c265f81d27b8d3bb5f250fce11e","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"tigredonorte","email":"tigredonorte3@gmail.com"},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.14.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.15.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.15.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.0.0_1786132933827_0.8576514362609926","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@12-apps/pwa","version":"1.1.1","license":"MIT","_id":"@12-apps/pwa@1.1.1","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"ad50113e7c904bbd63ff258c2f8216686a69d20c","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.1.1.tgz","fileCount":8,"integrity":"sha512-EScDPfk9sfQPcXoOXFj26S+3S7BoNLzIfyJQzi32r6yxv9FQP9axSNeSvndEdp8wQ6ZcTQmRmVJgTxQGmhaYww==","signatures":[{"sig":"MEUCIQC6i2eOEcHwQ9cZ/wuq3qD+iuDQsWvX7rio5Lt8JtWECQIgFkrUrHHta7FSIQvK67NFSkASP6OjaddmEtZMmKh5EBk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"bfd39495ffa882cae31b10538877b522984cbebc","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.15.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.16.2","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.16.2","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.1.1_1786138886177_0.3110021996130079","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@12-apps/pwa","version":"1.2.0","license":"MIT","_id":"@12-apps/pwa@1.2.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"a1a235b4fac09f1b27e736f248a8812db9a30165","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.2.0.tgz","fileCount":8,"integrity":"sha512-rYS5NknImdBBPinR5yGWJBCA4rMbX8DiZYg6yPM+cHJQ8LksuCI3+vbf9Sqt+sPdPaI0/FlrD8jD6IEkZdIZvw==","signatures":[{"sig":"MEQCIAc1FC/HhonMG5TFc5n9W0NWhKKd1Yxxl+Vm1RKsMJ4FAiAkfaN2DnbDpHvw5C00hhHSWrpy3NHf8xd7s4ylcQl2JA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"2d4a0e9dbf04f79e2306b779f56f0dd5d079e09a","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.16.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.17.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.17.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.2.0_1786145591301_0.6825123407747946","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@12-apps/pwa","version":"1.2.1","license":"MIT","_id":"@12-apps/pwa@1.2.1","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"d146978839f291be7d44aed6c9147aa417a24916","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.2.1.tgz","fileCount":8,"integrity":"sha512-m47P1cmsgBNpRXcGdqM00rZI8PaVPG+/WKqbq8QmFaiUYCe0+the6rqAQtwyiXvEk5F2lrHAYKw/VVAbN3BQGw==","signatures":[{"sig":"MEUCIDsRqEQftf89OYhssKb5BhXtnArKk8uQsDxObU0l8x2OAiEAwJOdDXe0x1Eu7Ayb7lSb9aBYwVxs4q+9TTDIwIvumOQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"f0356169f9682182eabba77485cf4772051235ae","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.16.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.17.1","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.17.1","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.2.1_1786146733999_0.36894112068595053","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@12-apps/pwa","version":"1.2.2","license":"MIT","_id":"@12-apps/pwa@1.2.2","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"407a671b6f1ab5762d0f155fbbd71666a9a22f12","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.2.2.tgz","fileCount":8,"integrity":"sha512-7mLZEZp1dXTBx9BNtwEIZNQhAluaL+DtP6KW74xaoPekymdHmLXUXadKor6Dtui+D8Ht0L+kFdWrO3X6KOkwmg==","signatures":[{"sig":"MEUCIEwbsMOlic8ZWEgdClvqsOj6Dyc2xKbk8D2leJEp3rKUAiEAtYyoK21uqfQdBkGPHUvYifmpJkvbhcHJEhDjgBbhhAk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"4b2466cbe6cded4941ec25ef92cf41d7fab0697e","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.16.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.17.2","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.17.2","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.2.2_1786159990805_0.14944657647934134","host":"s3://npm-registry-packages-npm-production"}},"1.2.3":{"name":"@12-apps/pwa","version":"1.2.3","license":"MIT","_id":"@12-apps/pwa@1.2.3","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"977081fed28b973e2b1e6187f3c5d67e1b7d6937","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.2.3.tgz","fileCount":8,"integrity":"sha512-tZGk9ePFCa3kR6uBj+81FKKxaqaWOK0qHCEIZ9l49ElSIzLGT1kd/MFv/3GMQWLls/4BzyNU4tjhsjtdUw2+ag==","signatures":[{"sig":"MEYCIQCyqvpayvzRArowzbi67tqoLwDB9h/Q9U3LikjqEwmtzwIhAPmDWFm43dFYMsx4yICoLuyzRuuUYZ0olzLvGsZjneBe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"ee3399530780d82beea32410802a945627ffe271","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.16.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.17.3","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.17.3","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.2.3_1786197965797_0.5221185479446724","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@12-apps/pwa","version":"1.3.0","license":"MIT","_id":"@12-apps/pwa@1.3.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"7818e0c8b69f04255ac82bcee41948f778c8961d","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.3.0.tgz","fileCount":8,"integrity":"sha512-FFvPZzHoMsiN05ipubswCvijV3yJ1u9C3ZAD5QlNFSrQdA3oLQr1aJD7Q/EOeSzwLNn83XtEIH649bzrldPGBA==","signatures":[{"sig":"MEUCIHI8m+BmFaE86+D8b5wkSQQftghZW+zARskkGeVyJVYBAiEAul0e+sTmTvzXLF+4LqaOubPGKNRzDBfSrg2v918WAZI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"8af3c18e1811d042f30016a4ba43e74abc4b8c50","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.17.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.18.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.18.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.3.0_1786203939527_0.9344209633805096","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@12-apps/pwa","version":"1.4.0","license":"MIT","_id":"@12-apps/pwa@1.4.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"ad3d0c063db5d74cdd690277ff26cbb402cefbaa","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.4.0.tgz","fileCount":8,"integrity":"sha512-RUX/m6n2QbUOnCGp4ow5gI1nGiROvxAQru2Kg6gquHZRchjO8QrvA1fZwyOoU0/hk8U5VvqpO6o3TOVEPX8Qfg==","signatures":[{"sig":"MEUCIDHnC5mBPL7Ya6jBkWgUysuv19XGLwXzdcWjciOnmhCrAiEAmPA5RYYFGElQ34nYL8ulwhPAlAJ+DrBrRCoY+r8fn60=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"3a8eb1783f8cccce3b7ec49cb10e3e6d2c5d7310","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.18.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.19.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.19.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.4.0_1786206142264_0.3921225027038162","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@12-apps/pwa","version":"1.5.0","license":"MIT","_id":"@12-apps/pwa@1.5.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"a8e457a30e71636b1f577ae6da798351d50c579a","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.5.0.tgz","fileCount":8,"integrity":"sha512-9o4YbBsiueXF+1YRvfw94VROM0J6AfIFjJKizXDekYGXUYtBKR6cOI4JiuFyOTHslrhMseGiO3k/0UMmO1X6Vg==","signatures":[{"sig":"MEUCIE0zAAMPF/zi2vQ62DvTT3aJs7S938GJCB/pdPvRqMrOAiEA5n4F2s4Q+OX5IgGLvN2yFeM+xVYHSqBSm609XFosFP4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":29518},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./react":"./src/react/index.ts"},"gitHead":"21bbb5b06424cf045eaad617a5912aa00d0c654b","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is. Captures beforeinstallprompt without ever firing it, detects the iOS browsers where installation is a manual share-sheet action, and ships an invite that leads with the reason rather than the instruc","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@12-apps/ui":"^1.19.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.20.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.20.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"react":">=19.0.0","react-dom":">=19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.5.0_1786209487468_0.015250001906047306","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@12-apps/pwa","version":"1.6.0","license":"MIT","_id":"@12-apps/pwa@1.6.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"789b15c03999b3339d21b071bec2ff108b3c04ea","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-1.6.0.tgz","fileCount":15,"integrity":"sha512-nSqUC8bR5q6NT35N48BS2OB1DWueKWVRz6BWL+7OeeAd1WLAOo7PVnUmaOhQz7F/kTf4UmGQabQI3dVLFhMfbA==","signatures":[{"sig":"MEUCIQDcyZRZiWrc4/BHczQ7AT7rlGFoz92EhkfggLE1oS2W2gIgTK4y2aOK4bDW9PCe8UKgidvJz9t0D2pUl4SvWSKYPrA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@1.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72450},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./server":"./src/server/index.ts","./package.json":"./package.json"},"gitHead":"a470e8b821b0aa209090194eaea60deb3ad07974","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@12-apps/ui":"^4.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.20.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.20.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0"},"peerDependenciesMeta":{"hono":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_1.6.0_1786588169081_0.8780138662746277","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@12-apps/pwa","version":"2.0.0","license":"MIT","_id":"@12-apps/pwa@2.0.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"a045ef6cc8fdd7f409a008aa6690f6c6be648e6e","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.0.0.tgz","fileCount":15,"integrity":"sha512-V5DABiRALbgqLrpHpEJHmruSxQ7XcTFySsTGU7pqgoNBD/9DTjsbgOn+cEZCtmlu3KcOp2Wwj2IwzA3J3H5iaA==","signatures":[{"sig":"MEUCIQCdn2sYI1M+0ZcvKXQZthpgDfygXeWdLLgiU/lgvI/olAIgT19kC8K74kZlMpnptGbx+ZvmVkzMH6qS8of20/gFMWM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72510},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./server":"./src/server/index.ts","./package.json":"./package.json"},"gitHead":"f837d4958a5b21e02d2f02a1c008ff1d1a23937a","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@12-apps/ui":"^5.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.20.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.20.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0"},"peerDependenciesMeta":{"hono":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_2.0.0_1786800363706_0.7307529931294496","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@12-apps/pwa","version":"2.1.0","license":"MIT","_id":"@12-apps/pwa@2.1.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"4ea38dc669c5210089c48458c97f95c241f75be7","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.1.0.tgz","fileCount":16,"integrity":"sha512-bcM21mAa+5MnTvQLoRwbVcmSePQY8r7M035q0Uz5IKhPpVP9BrktsDasGMDhOs1ossRd1Z5cnTya17wP+1aQWw==","signatures":[{"sig":"MEUCIQC3iBoth4wEbdatFQr8BZQe/BK+ePBxMEr0bsgUXo+HVgIgJEYvyaaBELOEZ2RAneWkBz7S09OdUCvwIREupHHldBc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72710},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./server":"./src/server/index.ts","./package.json":"./package.json"},"gitHead":"3c4711049bf8351685612372531c3cae1370bbbb","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:778ef7c0-3f9d-42ea-91bc-db7683bb5f87"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@12-apps/ui":"^6.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/eslint-config":"^1.21.1","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.20.1","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0"},"peerDependenciesMeta":{"hono":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_2.1.0_1787327332662_0.8591002818243971","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@12-apps/pwa","version":"2.2.0","license":"MIT","_id":"@12-apps/pwa@2.2.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"8d201dfbb820f4d46fb513e2c317e145760c7445","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.2.0.tgz","fileCount":18,"integrity":"sha512-q1FNn/J409/nqiT4CnD5z0gZipBGVNZQT4KqWM5S0Y9YGMOtTv+fL1jJpmVFX9oi0M20rFZHx8OGHj55VAa0og==","signatures":[{"sig":"MEQCIAt4grPTsUietzASSChV2i1WD9U6k2WsBoSh4/zzJmFlAiA2jgedY0y3du4hq07R9kIthkzpguzAM0uvMV39a6puHA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":74709},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./server":"./src/server/index.ts","./package.json":"./package.json"},"gitHead":"9aa6a7b4c316ceed44033000e57b1b02c316537b","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2d282f1d-35c3-4838-8b14-ab1b8c421dca"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@12-apps/ui":"^6.9.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/i18n":"^1.0.0","@12-apps/eslint-config":"^1.21.1","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.20.1","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0"},"peerDependenciesMeta":{"hono":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_2.2.0_1787547320236_0.24659345427150292","host":"s3://npm-registry-packages-npm-production"}},"2.3.0":{"name":"@12-apps/pwa","version":"2.3.0","license":"MIT","_id":"@12-apps/pwa@2.3.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"218ea72d23b548e13b55dfb20b5506966dfaf863","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.3.0.tgz","fileCount":21,"integrity":"sha512-G0yH7QlMGWGxLr6Fr009iARLK+ul0XPxLqHjCZfV/kfKRy67U8MiRQEGtT5zn/Ivp2RP+WftBNx+nAhMBsDmhA==","signatures":[{"sig":"MEQCIFDPhwhzE0bb2kPlK7uJZQIHbj/BaPm1U7BNSUkuOt86AiBe7dat+zfBpKOGGPRtB6V/XgOebRMRIwbLqGm+2WTb/g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":83507},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./server":"./src/server/index.ts","./manifest":"./src/manifest/index.ts","./package.json":"./package.json","./manifest/server":"./src/manifest/server.ts"},"gitHead":"7214db3f0537b1f81937a8c40470c589325ed661","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2d282f1d-35c3-4838-8b14-ab1b8c421dca"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@12-apps/ui":"^6.9.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/i18n":"^1.1.0","@12-apps/wiring":"^1.12.0","@12-apps/eslint-config":"^1.21.1","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.20.1","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0","@12-apps/wiring":">=1.9.0"},"peerDependenciesMeta":{"hono":{"optional":true},"@12-apps/wiring":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_2.3.0_1787587522778_0.07507215541266432","host":"s3://npm-registry-packages-npm-production"}},"2.4.0":{"name":"@12-apps/pwa","version":"2.4.0","license":"MIT","_id":"@12-apps/pwa@2.4.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"85233bdbade20c959b21bf33d89e93ade1c9bafb","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.4.0.tgz","fileCount":21,"integrity":"sha512-tk2/4lGCYv3ADwkgvJjWfnU6GOf0hWVwwN5i57ej8zw4AUWvZa/LOA7Vp+tWJ6QqI1cjUEFy7oTTrNkQ0WxmbQ==","signatures":[{"sig":"MEUCIHLcVaT3KRRb0IXWMNkYj6ZdFJ6Jb+UsqlHl9mVYXeLSAiEA9WcC7jUcc0ppR4dWQ2BEkBm09j6HCmVVWLdwgQzVmCk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":83532},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./server":"./src/server/index.ts","./manifest":"./src/manifest/index.ts","./package.json":"./package.json","./manifest/server":"./src/manifest/server.ts"},"gitHead":"4714bd10c901bcc51544843d5d6091cc1509e649","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2d282f1d-35c3-4838-8b14-ab1b8c421dca"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{"@12-apps/ui":"^6.10.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/i18n":"^1.2.0","@12-apps/wiring":"^1.14.0","@12-apps/eslint-config":"^1.22.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.21.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0","@12-apps/wiring":">=1.9.0"},"peerDependenciesMeta":{"hono":{"optional":true},"@12-apps/wiring":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_2.4.0_1787617919847_0.7745083430206903","host":"s3://npm-registry-packages-npm-production"}},"2.5.0":{"name":"@12-apps/pwa","version":"2.5.0","license":"MIT","_id":"@12-apps/pwa@2.5.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"0d0917d7b12fbf9b8968abdeaa12738f6be9547e","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.5.0.tgz","fileCount":25,"integrity":"sha512-DnYVamYrobFsILSJGUI/3DnVrsCN1EVH6uK1itHe5diecJijttKrFgoIMNIWyHpP30T5uhvakLGn5XwYaPjUzg==","signatures":[{"sig":"MEQCIGgIz7es6K/WJOafT3mxkg5JRlOfYMQ47NDWdIV6BsbtAiAFG9F46URoAjBMYoLrz9DLdGk+0Zk0pqvHZLF9/PNDnA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":124083},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./server":"./src/server/index.ts","./manifest":"./src/manifest/index.ts","./package.json":"./package.json","./manifest/server":"./src/manifest/server.ts"},"gitHead":"ae6ce8af28858ac0c4d19491f3be8de9e8198812","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2d282f1d-35c3-4838-8b14-ab1b8c421dca"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{"@12-apps/ui":"^6.15.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/i18n":"^1.3.0","@12-apps/wiring":"^1.16.0","@12-apps/eslint-config":"^1.22.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.21.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0","@12-apps/wiring":">=1.9.0"},"peerDependenciesMeta":{"hono":{"optional":true},"@12-apps/wiring":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_2.5.0_1788469635678_0.5384347576696837","host":"s3://npm-registry-packages-npm-production"}},"2.6.0":{"name":"@12-apps/pwa","version":"2.6.0","license":"MIT","_id":"@12-apps/pwa@2.6.0","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"5ad218c27ca4f9033a1b6112860bc2fb67425b51","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.6.0.tgz","fileCount":25,"integrity":"sha512-cBWnmWCpitNF4z/fRVvPvvWuRxf/YnKEhoIATbueJQOv7Z8EAv9b24iGBkZL4lP5XiTtJ9C/9m4K2HoRhWPAbQ==","signatures":[{"sig":"MEUCIQD16G7vkzlVeYIb3zcEOEJnYYv2h7EXTyLPTDp3hCenmAIgGT83z5pgbX78r7lO2MlPxm1j5/WG1WWya9sNN8QuTH4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":128043},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./server":"./src/server/index.ts","./manifest":"./src/manifest/index.ts","./package.json":"./package.json","./manifest/server":"./src/manifest/server.ts"},"gitHead":"dfef5b6f2d45bd188987cdc9d323d50448a0e2d4","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2d282f1d-35c3-4838-8b14-ab1b8c421dca"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","dependencies":{"@12-apps/ui":"^6.15.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/i18n":"^1.3.0","@12-apps/wiring":"^1.16.0","@12-apps/eslint-config":"^1.22.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.21.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0","@12-apps/wiring":">=1.9.0"},"peerDependenciesMeta":{"hono":{"optional":true},"@12-apps/wiring":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_2.6.0_1788471878077_0.1504084871496203","host":"s3://npm-registry-packages-npm-production"}},"2.6.1":{"name":"@12-apps/pwa","version":"2.6.1","license":"MIT","_id":"@12-apps/pwa@2.6.1","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"homepage":"https://github.com/12-apps/shared-packages#readme","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"dist":{"shasum":"ad0dbf0827a5fe57616000ba3869263a9a5a08ab","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.6.1.tgz","fileCount":29,"integrity":"sha512-pDQiX9aaj933kE4kMFRktaF15pIlZTDI25svtCU1arlaIIirWccPAF2iavr/6om/+lBfhYMLkWIgX2D322F4eg==","signatures":[{"sig":"MEUCIBupSNQrxo4t4pUHLxr2nLlACtgRuzIRuNAkoVHGfCv6AiEAuvTB6XiOeOnqmvlYGjEEfkoJvlUks2008+YJhJXGdkg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":133427},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":"./src/index.ts","./hono":"./src/hono/index.ts","./react":"./src/react/index.ts","./reload":"./src/reload.ts","./server":"./src/server/index.ts","./locales":"./src/locales.ts","./manifest":"./src/manifest/index.ts","./messages":"./src/messages.ts","./platform":"./src/platform.ts","./package.json":"./package.json","./pull-gesture":"./src/pull-gesture.ts","./manifest/server":"./src/manifest/server.ts","./react/install-invite":"./src/react/install-invite.tsx","./react/pull-to-refresh":"./src/react/pull-to-refresh.tsx","./pull-to-refresh-locales":"./src/pull-to-refresh-locales.ts"},"gitHead":"8e5473a74c62db99127594db97dd87de437ede66","scripts":{"lint":"eslint src --max-warnings 0","test":"node ../../scripts/vitest-with-teardown.mjs run","clean":"rm -rf node_modules coverage dist","typecheck":"tsc --noEmit","test:watch":"vitest watch","check-types":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2d282f1d-35c3-4838-8b14-ab1b8c421dca"}},"repository":{"url":"git+https://github.com/12-apps/shared-packages.git","type":"git","directory":"packages/pwa"},"_npmVersion":"12.0.2","description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","dependencies":{"@12-apps/ui":"^6.15.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","eslint":"^9.39.1","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"^5.9.2","@types/react":"^19.2.0","@12-apps/i18n":"^1.3.0","@12-apps/wiring":"^1.16.0","@12-apps/eslint-config":"^1.22.0","@testing-library/react":"^16.1.0","@12-apps/typescript-config":"^1.21.0","eslint-plugin-test-flakiness":"^1.4.0"},"peerDependencies":{"hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0","@12-apps/wiring":">=1.9.0"},"peerDependenciesMeta":{"hono":{"optional":true},"@12-apps/wiring":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pwa_2.6.1_1788492619744_0.017904916589265296","host":"s3://npm-registry-packages-npm-production"}},"2.6.2":{"name":"@12-apps/pwa","version":"2.6.2","type":"module","sideEffects":false,"description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","exports":{".":"./src/index.ts","./react":"./src/react/index.ts","./react/pull-to-refresh":"./src/react/pull-to-refresh.tsx","./react/install-invite":"./src/react/install-invite.tsx","./reload":"./src/reload.ts","./pull-gesture":"./src/pull-gesture.ts","./messages":"./src/messages.ts","./locales":"./src/locales.ts","./server":"./src/server/index.ts","./hono":"./src/hono/index.ts","./manifest":"./src/manifest/index.ts","./manifest/server":"./src/manifest/server.ts","./package.json":"./package.json","./platform":"./src/platform.ts","./pull-to-refresh-locales":"./src/pull-to-refresh-locales.ts"},"scripts":{"clean":"rm -rf node_modules coverage dist","test":"node ../../scripts/vitest-with-teardown.mjs run","test:watch":"vitest watch","lint":"eslint src --max-warnings 0","check-types":"tsc --noEmit","typecheck":"tsc --noEmit"},"dependencies":{"@12-apps/ui":"^6.17.0"},"peerDependencies":{"@12-apps/wiring":">=1.9.0","hono":">=4.0.0","react":">=19.0.0","react-dom":">=19.0.0"},"peerDependenciesMeta":{"@12-apps/wiring":{"optional":true},"hono":{"optional":true}},"devDependencies":{"@12-apps/eslint-config":"^1.22.0","@12-apps/i18n":"^1.3.0","@12-apps/typescript-config":"^1.21.0","@12-apps/wiring":"^1.16.0","@testing-library/react":"^16.1.0","@types/react":"^19.2.0","eslint":"^9.39.1","eslint-plugin-test-flakiness":"^1.4.0","hono":"^4.6.0","jsdom":"^26.1.0","react":"^19.2.0","react-dom":"^19.2.0","typescript":"^5.9.2","vitest":"^3.2.4"},"engines":{"node":">=22.0.0"},"license":"MIT","publishConfig":{"registry":"https://registry.npmjs.org","access":"public"},"repository":{"type":"git","url":"git+https://github.com/12-apps/shared-packages.git","directory":"packages/pwa"},"gitHead":"7ccfaab8b27cf404c0039faf34434287e5c7c8bc","_id":"@12-apps/pwa@2.6.2","bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"homepage":"https://github.com/12-apps/shared-packages#readme","_nodeVersion":"24.20.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-bD+XvLGEhXY0dBIxq266EjQWsvJlQOGpFEdlf9Jcsl2pEh6FT0tlR6N9BqW6DRvcgKa2hafHLb2Cil5NzgFicA==","shasum":"455b898746d019c9125b38198f75b64b7bf4338d","tarball":"https://registry.npmjs.org/@12-apps/pwa/-/pwa-2.6.2.tgz","fileCount":31,"unpackedSize":143878,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@12-apps%2fpwa@2.6.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIChmK/q0RI3gKYYN2ZA77zd9xxBzUsBYSz1AO8njOjIWAiAC99HTrMuzH/+yHJUL1EEhDo8VNgeAHY2F4BY6dAE8rA=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2d282f1d-35c3-4838-8b14-ab1b8c421dca"}},"directories":{},"maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pwa_2.6.2_1788572439057_0.021734971730122732"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-07T20:02:13.653Z","modified":"2026-09-05T01:40:39.595Z","1.0.0":"2026-08-07T20:02:13.975Z","1.1.1":"2026-08-07T21:41:26.364Z","1.2.0":"2026-08-07T23:33:11.475Z","1.2.1":"2026-08-07T23:52:14.131Z","1.2.2":"2026-08-08T03:33:10.950Z","1.2.3":"2026-08-08T14:06:05.969Z","1.3.0":"2026-08-08T15:45:39.672Z","1.4.0":"2026-08-08T16:22:22.400Z","1.5.0":"2026-08-08T17:18:07.609Z","1.6.0":"2026-08-13T02:29:29.217Z","2.0.0":"2026-08-15T13:26:03.863Z","2.1.0":"2026-08-21T15:48:52.828Z","2.2.0":"2026-08-24T04:55:20.380Z","2.3.0":"2026-08-24T16:05:22.917Z","2.4.0":"2026-08-25T00:32:00.010Z","2.5.0":"2026-09-03T21:07:15.815Z","2.6.0":"2026-09-03T21:44:43.835Z","2.6.1":"2026-09-04T03:30:19.896Z","2.6.2":"2026-09-05T01:40:39.226Z"},"bugs":{"url":"https://github.com/12-apps/shared-packages/issues"},"license":"MIT","homepage":"https://github.com/12-apps/shared-packages#readme","repository":{"type":"git","url":"git+https://github.com/12-apps/shared-packages.git","directory":"packages/pwa"},"description":"Making a web app installable, and telling people it is: the beforeinstallprompt state machine + iOS share-sheet detection + overridable pt-BR copy (.), the install invite (./react), the PER-HOST manifest endpoint and the packaged network-first service wor","maintainers":[{"name":"tigredonorte","email":"tigredonorte3@gmail.com"}],"readme":"# `@12-apps/pwa`\n\nMaking a web app installable, and telling people it is.\n\nCaptures `beforeinstallprompt` without ever firing it, recognises the iOS\nbrowsers where installation is a manual share-sheet action, and ships an invite\nthat leads with the reason rather than the instruction. Host-agnostic: every\nstring comes from an overridable pt-BR messages layer.\n\n## Usage\n\n```tsx\nimport { InstallInvite } from \"@12-apps/pwa/react\";\nimport { reportWarning } from \"@12-apps/observability-frontend\";\n\n<InstallInvite\n  what={store.displayName}\n  enabled={isStoreOwnDomain}\n  onDiagnostic={reportWarning}\n/>\n```\n\n| entry | what it is |\n|---|---|\n| `@12-apps/pwa` | `useInstallPrompt`, `isIosInstallable`, `isStandalone`, `isHandheld`, the messages layer, `registerServiceWorker` / `postToServiceWorker`, and the **reload** half — `needsPullToRefresh`, `isInstalledHandheld`, `reloadApp`, `createPullTracker` |\n| `@12-apps/pwa/react` | `InstallInvite`, `ShareIcon`, `PullToRefresh` |\n| `@12-apps/pwa/server` | `createApiPwa({ resolveApp })` — the per-host **manifest endpoint** and the packaged service worker; also `buildWebAppManifest` and `pwaServiceWorkerSource` |\n| `@12-apps/pwa/hono` | `pwaRouter({ resolveApp })`, mounted at the origin root. `hono` is an OPTIONAL peer |\n\nThe root entry is framework-free, so a host that only needs \"can this be\ninstalled\" does not pull React in through a barrel it did not ask for.\n\n**[ADOPTING.md](./ADOPTING.md) is the adoption contract** — the config table and\nthe five wiring rules that bite.\n\n## What makes an app installABLE (12-23)\n\nThe invite above only *asks*. Two things have to exist first, and both ship here:\n\n1. **A manifest, as an ENDPOINT — never a static file.** A PWA's identity IS its\n   origin, and a bundle has exactly one `index.html` for every tenant it serves,\n   so a static `manifest.webmanifest` cannot vary by the store the visitor is\n   looking at. `resolveApp` returning `null` is a 404, and that 404 is the whole\n   installability gate.\n2. **A REGISTERED service worker, on every visit.** `registerServiceWorker()`\n   belongs at app boot, not behind a settings screen: the origin host registered its\n   worker only from `enableWebPush()`, so a visitor who never opened notification\n   preferences had no worker — and the browser never offered to install the store.\n\n```ts\nconst pwa = pwaRouter({ resolveApp: ({ host }) => appForHost(host) });\napp.route('/', pwa.router);           // the manifest, at the ORIGIN ROOT\nregisterServiceWorker();              // in the SPA's entry, once\n```\n\n**The packaged worker is network-first for documents, and that is not a\npreference.** Every hashed filename in a bundled SPA dies with the deploy that\nproduced it, and a history fallback answers a vanished chunk with `index.html` —\nwhich fails on the MIME type, reaches `React.lazy`, and renders the page blank. A\nnaive cache-first worker pins that old shell and makes the blank page PERMANENT;\non an installed app \"force-refresh\" is advice the user cannot follow.\n\n## Getting the reload back\n\nInstalling the app takes the address bar away, and with it the reload button —\nwhich is fine right up to the moment the app is wedged: a shell from an old\ndeploy, a session that expired without the page noticing, a screen whose one\nfetch failed. This package already says what that costs, in rule 5 of\n[ADOPTING.md](./ADOPTING.md): *on an installed app \"force-refresh\" is advice the\nuser cannot follow.* The worker fixes the half that can be fixed without the\nuser. `PullToRefresh` is the other half.\n\n```tsx\nimport { PullToRefresh } from \"@12-apps/pwa/react\";\nimport { PULL_TO_REFRESH_MESSAGES } from \"@12-apps/pwa\";\n\n<PullToRefresh messages={PULL_TO_REFRESH_MESSAGES[\"pt-BR\"]} onDiagnostic={reportWarning}>\n  <App />\n</PullToRefresh>\n```\n\n**Wrapping the whole app costs nothing where it is not needed**, because there\nit mounts nothing at all. `needsPullToRefresh()` is the gate, and it is true on\nexactly one combination:\n\n| where | has a reload? | why |\n|---|---|---|\n| any browser tab | yes | address bar, plus the browser's own overscroll refresh |\n| Chromium standalone (Android) | yes | **it keeps that overscroll refresh when installed** — unless the app itself opted out with `overscroll-behavior-y: contain \\| none` |\n| desktop standalone | yes | no address bar, but `Ctrl+R` and a context menu |\n| **iOS home screen** | **no** | no chrome, and the pull gesture that reloads in Safari does not reload a standalone web app. The workaround in the wild is *delete the icon and add it again* |\n\nSo by default the gesture ships to iOS and nowhere else — not because it would\nbe *unsafe* elsewhere, but because a platform gesture that already works has\nnative feel and haptics and cannot be lost to a JavaScript failure.\n\n**To use it on Android too, pass `platform={isInstalledHandheld}`.** That is a\nsupported choice, not a workaround, and the handover is clean rather than\ndoubled: mounting sets `overscroll-behavior-y: contain`, which is exactly the\nproperty that switches Chromium's own overscroll refresh off. One pull, one\ngesture, and it is yours — same indicator and same threshold on both platforms.\nIt also fails in the safe direction: if the bundle never runs, the property is\nnever set and Chromium's gesture is still there.\n\nReach for it when you want one gesture to design and support across every phone,\nor for an Android browser whose installed apps do *not* keep the native one.\nNote what you give up: on Android you are replacing a gesture the platform\nmaintains with one you maintain.\n\n`isInstalledHandheld` deliberately excludes a DESKTOP installed app — no address\nbar, but `Ctrl+R`, a context menu, and no touchscreen to pull on. An end-to-end\ntest driving a desktop browser passes `() => true`.\n\n### Import the gesture from its own path, not the barrel\n\nA host mounts `PullToRefresh` at its app ROOT, so whatever that import reaches\nis on its critical path. `@12-apps/pwa/react` re-exports `InstallInvite`, and\n`@12-apps/pwa` re-exports the invite's message packs and the\n`beforeinstallprompt` state machine — so importing the gesture from either\nbarrel puts the invite in the entry's module graph, and a bundler then folds the\ninvite's small chunk down into the entry.\n\nThat is measured, not theoretical. In a host that mounts the gesture at its\nroot, the install invite moved out of a lazy chunk and **into the entry chunk**:\n+9.3 KiB raw / +2.4 KiB brotli of first-paint code that only ever runs on a\ncheckout confirmation screen.\n\n```ts\n// on the critical path — reaches the gesture and nothing else\nimport { PullToRefresh } from \"@12-apps/pwa/react/pull-to-refresh\";\nimport { PULL_TO_REFRESH_MESSAGES } from \"@12-apps/pwa/pull-to-refresh-locales\";\nimport { isInstalledHandheld } from \"@12-apps/pwa/reload\";\n```\n\nThe barrels are still correct for a host importing the invite anyway, or one\nthat does not gate on bundle size. Three splits make the narrow path possible\nand none of them change a public name: `platform.ts` holds the three predicates\nwith no React, `pull-to-refresh.{pt-BR,en-US}.ts` hold the gesture's copy away\nfrom the invite's, and every original module re-exports what moved.\n\n### `reloadApp()` is not quite `location.reload()`\n\nThe open document is controlled by whichever worker was active when it loaded,\nand the browser's own update check races the navigation rather than preceding\nit — so a reload issued the moment a deploy lands can still be served by the\noutgoing worker, handing back the very shell the user was trying to escape.\n`reloadApp()` asks for the update first and waits for it, bounded (2s by\ndefault) because the person who just pulled down is usually the person whose\nnetwork is having a bad day. Every failure path still reloads: a reload the user\nasked for is never something the app declines to do.\n\n### What the gesture will not take\n\nThree things it must not break, each prevented by construction rather than by a\ncheck somebody has to remember:\n\n- **Scrolling.** The first 12px of travel are *watched and not consumed* —\n  `preventDefault()` is called only once the tracker claims the gesture, which\n  it never does for a finger moving up or sideways.\n- **Anything in a portal.** The listeners are on the component's own subtree,\n  so a MUI `Drawer` or `Dialog` — rendered into `document.body`, a sibling of\n  everything inside — cannot reach them.\n- **Nested scrollers.** A list already scrolled down keeps its own pull. A\n  region that wants its vertical drags for something else says so in the markup:\n  `data-pull-refresh=\"off\"`.\n\nThe wrapper is `display: contents`, so it changes no layout: children stay their\nparent's own flex or grid items. `offsetTop` and `zIndex` place the indicator\nabove the host's fixed chrome — exposed rather than hard-coded, because the app\nthat adopted the install invite had to override *its* fixed placement with\n`!important`.\n\n## Two platforms that share nothing\n\n**Chromium** fires `beforeinstallprompt`, which is captured and **held** — never\nfired automatically. A browser lets a page ask once, and asking on a first\nvisit, before the visitor knows what the app is, spends that one chance on a\nnear-certain \"no\" the browser then remembers for a long time. The button is the\nvisitor's.\n\nNote it fires on **desktop** as readily as on Android, so the copy is chosen by\n`(pointer: coarse)` rather than assuming a phone.\n\n**iOS has no API at all**, in any browser. Not provisionally: there is no\n`beforeinstallprompt` in Safari 26.0–26.6 or 27 beta, MDN's compat data records\n`safari: false` with `safari_ios` and `webview_ios` mirroring it — and\n`webview_ios` is what every iOS browser is, Chrome included — and WebKit's\nstandards position on the Web Install API (`navigator.install`) is **oppose**.\nDesign for the share sheet.\n\n`isIosInstallable()` deliberately does not check *which* browser. Excluding\n`CriOS`/`FxiOS`/`EdgiOS` was right before March 2023 and a bug since: iOS 16.4\nopened \"Add to Home Screen\" to any browser with the\n`com.apple.developer.web-browser` entitlement, so excluding them told a large\nshare of iPhone users nothing at all.\n\n## The iOS instruction is where the design work is\n\nA one-tap button converts on its own. A written instruction has to survive being\nread, understood, and then acted on against a control the person has never\ndeliberately looked at — in the two seconds they spend glancing at a banner.\nThree things follow, each replacing something the obvious version got wrong:\n\n1. **The reason leads.** The first version opened with \"add to your Home\n   Screen\" and demoted the payoff to grey caption text. Nobody adds a site to\n   their Home Screen because they want to add a site to their Home Screen. On\n   iOS the payoff is also literally gated — web push does not exist outside an\n   installed app — so \"get told when it is ready\" is *unavailable* until they do\n   it. That is the headline.\n2. **The glyph, not the word.** \"Tap Share\" asks for a translation from a word\n   to a shape. `ShareIcon` is the same shape that is in the browser chrome, so\n   there is nothing to translate. Drawn inline: the SF Symbol is Apple's, and an\n   icon font would be a network round-trip in a component whose whole job is to\n   be understood immediately.\n3. **It points.** Safari's share control is in the **bottom** bar, and a banner\n   at the top of the page points at nothing. `placement=\"anchored\"` (the\n   default) fixes the card just above the control and aims a chevron at it.\n   `placement=\"inline\"` opts out when the host is already placing it low.\n\n**Be honest about the ceiling.** None of this makes iOS install *well* — Apple\ngives no API and conversion is poor everywhere. This is a discovery affordance,\nnot a funnel, and worth measuring rather than assuming.\n\n## Diagnostics\n\nAn invite that declines to appear fails **silently**: nothing throws, so a\nbroken one looks exactly like a healthy page. `onDiagnostic` is told once per\nmount, with a payload that reads as a decision table:\n\n| field | what `false` means |\n|---|---|\n| `earlyScriptPresent` | the document predates the inline capture — deploy |\n| `earlyEventHeld` | the browser never judged the page installable |\n| `earlyEventFiredAt` set but `hasDeferred` false | the stash is not being adopted |\n| `installed` / `dismissed` true | working as designed, not a fault |\n\n## Tests\n\n```bash\npnpm --filter @12-apps/pwa test\n```\n","readmeFilename":"README.md"}