{"_id":"@capsium/reactor-cloudflare","_rev":"2-9fb82db1cb9a5a3a7be9d0977e37db89","name":"@capsium/reactor-cloudflare","dist-tags":{"latest":"0.2.1"},"versions":{"0.2.0":{"name":"@capsium/reactor-cloudflare","version":"0.2.0","license":"MIT","_id":"@capsium/reactor-cloudflare@0.2.0","maintainers":[{"name":"ronaldtse","email":"ronald.tse@ribose.com"}],"homepage":"https://github.com/capsiums/capsium-js#readme","bugs":{"url":"https://github.com/capsiums/capsium-js/issues"},"dist":{"shasum":"ffe0bb46ba82a9859599fc679462309431fa7430","tarball":"https://registry.npmjs.org/@capsium/reactor-cloudflare/-/reactor-cloudflare-0.2.0.tgz","fileCount":7,"integrity":"sha512-3JNpYZwlNGXmuuTiZC+p6F2sARjwvfGwCB5sB7Ml1OSwJUz0t6vhB9cC9UJALZbexs0HojlZC94kC4VY/G88bw==","signatures":[{"sig":"MEQCICR0jOBddatdlj7BQS9TMnL2WPHKl978PZPGbninVsJgAiBtm1X7jdMfhfdACG4LKSmskGAlPzUVoH+IM/QU9Mog1Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2105751},"type":"module","engines":{"node":">=20"},"exports":{".":{"types":"./src/index.ts","import":"./src/index.ts"},"./worker":{"import":"./src/worker.ts"}},"gitHead":"98ba558a28e591407103c166230b5eee1448d640","scripts":{"lint":"eslint .","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"ronaldtse","email":"ronald.tse@ribose.com"},"repository":{"url":"git+https://github.com/capsiums/capsium-js.git","type":"git","directory":"packages/reactor-cloudflare"},"_npmVersion":"11.9.0","description":"Cloudflare Workers Capsium reactor: install .cap packages over HTTP (integrity + signature verified, persisted in the Cache API) and serve them per routes.json with the §7 introspection API.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"fflate":"^0.8.3","@capsium/core":"workspace:^"},"publishConfig":{"access":"public","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./worker":{"import":"./dist/worker.js"}}},"_hasShrinkwrap":false,"devDependencies":{"miniflare":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/reactor-cloudflare_0.2.0_1784651511847_0.6206626643049868","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@capsium/reactor-cloudflare","version":"0.2.1","description":"Cloudflare Workers Capsium reactor: install .cap packages over HTTP (integrity + signature verified, persisted in the Cache API) and serve them per routes.json with the §7 introspection API.","license":"MIT","type":"module","engines":{"node":">=20"},"repository":{"type":"git","url":"git+https://github.com/capsiums/capsium-js.git","directory":"packages/reactor-cloudflare"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./worker":{"import":"./dist/worker.js"}},"publishConfig":{"access":"public","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./worker":{"import":"./dist/worker.js"}}},"scripts":{"build":"tsup","test":"vitest run","lint":"eslint .","typecheck":"tsc --noEmit"},"dependencies":{"@capsium/core":"^0.2.1","fflate":"^0.8.3"},"devDependencies":{"miniflare":"^4.0.0"},"_id":"@capsium/reactor-cloudflare@0.2.1","bugs":{"url":"https://github.com/capsiums/capsium-js/issues"},"homepage":"https://github.com/capsiums/capsium-js#readme","_integrity":"sha512-Jmwd/6dOP4+AMZ2jSSmi1dBuEFbJH6RSusAst1/XMYJ1MRZdUMxTIS4gPg1BtIXfRULATcPqX/1xfHqKsPgRqg==","_resolved":"/home/runner/work/capsium-js/capsium-js/packages/reactor-cloudflare/package.tgz","_from":"file:package.tgz","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-Jmwd/6dOP4+AMZ2jSSmi1dBuEFbJH6RSusAst1/XMYJ1MRZdUMxTIS4gPg1BtIXfRULATcPqX/1xfHqKsPgRqg==","shasum":"9bb40adec49c40d4993cca5dd33d24322f8d0c4a","tarball":"https://registry.npmjs.org/@capsium/reactor-cloudflare/-/reactor-cloudflare-0.2.1.tgz","fileCount":7,"unpackedSize":2105750,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@capsium%2freactor-cloudflare@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDvO50C0HxcjMYKfa1zmitS4dJOJkkMN1BxUhkPLKMXdgIgPidaOXVOPiTjxdy41hn6hVRMu2tcntjFvkRUKcnL9Cs="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c87d8055-e1a2-457b-9c72-e15c2c0e3779"}},"directories":{},"maintainers":[{"name":"ronaldtse","email":"ronald.tse@ribose.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/reactor-cloudflare_0.2.1_1784652267524_0.260498531523468"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-21T16:31:51.626Z","modified":"2026-07-21T16:44:28.051Z","0.2.0":"2026-07-21T16:31:52.043Z","0.2.1":"2026-07-21T16:44:27.743Z"},"bugs":{"url":"https://github.com/capsiums/capsium-js/issues"},"license":"MIT","homepage":"https://github.com/capsiums/capsium-js#readme","repository":{"type":"git","url":"git+https://github.com/capsiums/capsium-js.git","directory":"packages/reactor-cloudflare"},"description":"Cloudflare Workers Capsium reactor: install .cap packages over HTTP (integrity + signature verified, persisted in the Cache API) and serve them per routes.json with the §7 introspection API.","maintainers":[{"name":"ronaldtse","email":"ronald.tse@ribose.com"}],"readme":"# @capsium/reactor-cloudflare\n\nCloudflare Workers reactor for [Capsium](https://github.com/capsiums) `.cap`\npackages. Install a package over HTTP and serve it per `routes.json` — with\nSHA-256 integrity verification (§6), RSA-SHA256 signature verification when\ndeclared (§6a), §5a layered storage, and the §7 introspection API — all from a\nsingle module-format Worker.\n\n## Quickstart (wrangler)\n\n```sh\nnpm install @capsium/reactor-cloudflare\n```\n\n`wrangler.toml`:\n\n```toml\nname = \"capsium-reactor\"\nmain = \"node_modules/@capsium/reactor-cloudflare/dist/worker.js\"\ncompatibility_date = \"2025-09-01\"\n\n[vars]\nINSTALL_TOKEN = \"change-me\"          # required for POST /__capsium/install\n# PACKAGE_URL = \"https://example.com/site.cap\"  # optional: install at startup\n# PATH_PREFIX = \"/docs\"              # optional: mount under a path prefix\n```\n\n```sh\nnpx wrangler deploy\n```\n\nInstall a package:\n\n```sh\ncurl -X POST \\\n  -H \"Authorization: Bearer change-me\" \\\n  -H \"Content-Type: application/vnd.capsium.package\" \\\n  --data-binary @my-package.cap \\\n  https://capsium-reactor.<account>.workers.dev/__capsium/install\n# => {\"ok\":true,\"name\":\"my-package\",\"version\":\"1.0.0\",\"contentHash\":\"…\"}\n```\n\nThen browse the package routes: `https://capsium-reactor.<account>.workers.dev/`.\n\n## HTTP API\n\n- `POST /__capsium/install` — install a `.cap` body. Requires\n  `Authorization: Bearer <INSTALL_TOKEN>` when the variable is set (missing/\n  malformed header → 401, wrong token → 403). **When `INSTALL_TOKEN` is not\n  set the endpoint is open — development mode only; always set a token before\n  deploying.** Verification failures are typed JSON problem bodies\n  (`{\"error\": \"…\"}`): 400 malformed archive/package, 422 checksum or\n  signature mismatch. Reinstalling replaces the previous package.\n- Package routes per `routes.json` — dual HTML routes, `/` index,\n  `/api/v1/data/<id>` datasets (JSON), §5a layered storage (tombstoned paths\n  404). `Cache-Control: public, max-age=31536000` by default; a route's own\n  `headers` override that wholesale. GET/HEAD only (405 + `Allow` otherwise),\n  handler routes 501, JSON 404s.\n- §7 introspection (GET/HEAD): `/api/v1/introspect/metadata`,\n  `/api/v1/introspect/routes`, `/api/v1/introspect/content-hashes`,\n  `/api/v1/introspect/content-validity`.\n\nAll paths are relative to the mount prefix when `PATH_PREFIX` is set (e.g.\n`/docs/__capsium/install`, `/docs/api/v1/introspect/metadata`); requests\noutside the prefix get a JSON 404.\n\n## Startup install\n\nWhen `PACKAGE_URL` is set and no package is installed, the first request\nfetches that `.cap` and installs it before being served — convenient for\nread-only deployments where the package is published next to the site.\nFailures are logged and the worker keeps serving 404s until a package\ninstalls successfully (retry on the next cold start, or via the install\nendpoint).\n\n## Persistence caveat (Cache API)\n\nInstalled packages are persisted **unzipped in the Cache API**\n(`caches.default`, one synthetic request key per file plus a small manifest\nentry). The Cache API is **per-colo and best-effort**: entries can be\nevicted at any time and are not replicated. The reactor re-verifies the\nstored package on every cold start and drops a damaged (partially evicted)\ninstall, but an eviction still means the package must be re-installed\n(`POST /__capsium/install`, or automatically when `PACKAGE_URL` is set).\nFor durable storage, backing the store with **R2 or Workers KV is a planned\nfollow-up** (the `CachePackageStore` is the single seam to replace).\n\n## Programmatic usage\n\nThe default worker entry is just `export default createWorker()`. For custom\nwiring (e.g. combining with your own routes), use the factory:\n\n```ts\nimport { createWorker } from '@capsium/reactor-cloudflare';\n\nconst capsium = createWorker({ installToken: 'change-me' });\n\nexport default {\n  async fetch(request: Request, env: Env, ctx: ExecutionContext) {\n    if (new URL(request.url).pathname.startsWith('/admin')) {\n      return new Response('your own route');\n    }\n    return capsium.fetch(request, env, ctx);\n  },\n};\n```\n\nOptions: `installToken`, `packageUrl`, `pathPrefix`, `cacheControl`, `cache`\n(each overrides its env counterpart where applicable).\n\n## Out of scope (deferrals)\n\n- §4a composite packages: the install endpoint takes a single `.cap`;\n  routes referencing `capsium://` dependencies answer 404.\n- §4b authentication (basic/OAuth2), JS handler execution (501), SQLite\n  datasets (501).\n- Durable persistence via R2/KV (see the caveat above).\n\n## Development\n\nYarn workspace package in the capsium-js monorepo. Tests run the bundled\nworker under miniflare (real workerd):\n\n```sh\ncorepack yarn install\ncorepack yarn workspace @capsium/reactor-cloudflare test\n```\n\nLicense: MIT.\n","readmeFilename":"README.md"}