{"_id":"@aletso/atom-query","_rev":"5-90b4877990dd22192dc12a0409c39e94","name":"@aletso/atom-query","dist-tags":{"latest":"0.1.7"},"versions":{"0.1.2":{"name":"@aletso/atom-query","version":"0.1.2","license":"MIT","_id":"@aletso/atom-query@0.1.2","maintainers":[{"name":"gbartman","email":"g.bartman@aletso.com"}],"dist":{"shasum":"1cd2c8f8c3d2f51311d32933698da9f923c36718","tarball":"https://registry.npmjs.org/@aletso/atom-query/-/atom-query-0.1.2.tgz","fileCount":31,"integrity":"sha512-0t0RHZK+5wPhyQzMUr76A1o57+im3i1muxUguobX2InSGhxd2yt4GwqWyrVmhunzdaZo8LMdCfHOdgTAfhxywQ==","signatures":[{"sig":"MEUCIC3nZioHHxmKcx9fzVeoge9a9POsKgJ1YZ5xAbGfHx7gAiEAxnmK305VTBovty8dpmhLet4vlqek20kphKu/Tx5L0xo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":106729},"type":"module","_from":"file:aletso-atom-query-0.1.2.tgz","exports":{"./*":"./dist/*.js"},"scripts":{"build":"tsc -b tsconfig.json","type-check":"tsc -b tsconfig.json"},"_npmUser":{"name":"gbartman","email":"g.bartman@aletso.com"},"_resolved":"/tmp/cda319ae4f2780ff09a5a10713c25377/aletso-atom-query-0.1.2.tgz","_integrity":"sha512-0t0RHZK+5wPhyQzMUr76A1o57+im3i1muxUguobX2InSGhxd2yt4GwqWyrVmhunzdaZo8LMdCfHOdgTAfhxywQ==","_npmVersion":"11.12.1","description":"Effect atom query layer with SWR, optimistic updates, and SSR preloading","directories":{},"_nodeVersion":"24.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@effect/language-service":"^0.62.3"},"peerDependencies":{"effect":"^3.19.12","@effect/rpc":"^0.72.2","@effect-atom/atom":"^0.5.2","@aletso/effect-route":"^0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/atom-query_0.1.2_1776189554461_0.6806407719713599","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@aletso/atom-query","version":"0.1.3","license":"MIT","_id":"@aletso/atom-query@0.1.3","maintainers":[{"name":"gbartman","email":"g.bartman@aletso.com"}],"dist":{"shasum":"14546d7cdf0e373a63ead5fb5edf7d2a6bb7fbb2","tarball":"https://registry.npmjs.org/@aletso/atom-query/-/atom-query-0.1.3.tgz","fileCount":32,"integrity":"sha512-UIfZYlIGqVMHICt09RuQUugLBUE9epiUY+hKKI7ghAhVeYFKBRNsJ9YxSZvkdWzvaqwKrl0A1fR/vO/5A0NRfg==","signatures":[{"sig":"MEUCIAeK36gwsefFqx7JheyWpVWPxiv+8C5k0kdPfPRPp3IVAiEAnTpy0AOVlCfv6I0rDcbc2aHjD4RterPcuYGNm+IrN6w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113345},"type":"module","_from":"file:aletso-atom-query-0.1.3.tgz","exports":{"./*":"./dist/*.js"},"scripts":{"build":"tsc -b tsconfig.json","type-check":"tsc -b tsconfig.json"},"_npmUser":{"name":"gbartman","email":"g.bartman@aletso.com"},"_resolved":"/tmp/b5ac3849139cce4be9df0467d2aeaa51/aletso-atom-query-0.1.3.tgz","_integrity":"sha512-UIfZYlIGqVMHICt09RuQUugLBUE9epiUY+hKKI7ghAhVeYFKBRNsJ9YxSZvkdWzvaqwKrl0A1fR/vO/5A0NRfg==","_npmVersion":"11.12.1","description":"Effect atom query layer with SWR, optimistic updates, and SSR preloading","directories":{},"_nodeVersion":"24.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@effect/language-service":"^0.62.3"},"peerDependencies":{"effect":"^3.19.12","@effect/rpc":"^0.72.2","@effect-atom/atom":"^0.5.2","@aletso/effect-route":"^0.1.3"},"_npmOperationalInternal":{"tmp":"tmp/atom-query_0.1.3_1776190710751_0.13840109121753574","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@aletso/atom-query","version":"0.1.5","license":"MIT","_id":"@aletso/atom-query@0.1.5","maintainers":[{"name":"gbartman","email":"g.bartman@aletso.com"}],"dist":{"shasum":"6b904b0874ecd072ada526141f01094e1e1a7ba5","tarball":"https://registry.npmjs.org/@aletso/atom-query/-/atom-query-0.1.5.tgz","fileCount":32,"integrity":"sha512-dTMkuL0meOZPhLbCs9N54feOA+fXeNtRjXOXQ7jVxDq1jlsezXvKc9TsXIU/VcAVW59A4Slmppz9xdUkzX8rNw==","signatures":[{"sig":"MEUCIG2mYwh/DLr5caw5WSxELRUmuHtOZsbYghFPTHbfR8MZAiEAhwJ/AYhdqrGFqykcsVS0M0jIymMoScVdRxDQmQYVenc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":119336},"type":"module","_from":"file:aletso-atom-query-0.1.5.tgz","exports":{"./*":"./dist/*.js"},"scripts":{"build":"tsc -b tsconfig.json","type-check":"tsc -b tsconfig.json"},"_npmUser":{"name":"gbartman","email":"g.bartman@aletso.com"},"_resolved":"/tmp/b45370eba363cec11eaf71da557dc9c6/aletso-atom-query-0.1.5.tgz","_integrity":"sha512-dTMkuL0meOZPhLbCs9N54feOA+fXeNtRjXOXQ7jVxDq1jlsezXvKc9TsXIU/VcAVW59A4Slmppz9xdUkzX8rNw==","_npmVersion":"11.12.1","description":"Effect atom query layer with SWR, optimistic updates, and SSR preloading","directories":{},"_nodeVersion":"24.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@effect/language-service":"^0.62.3"},"peerDependencies":{"effect":"^3.19.12","@effect/rpc":"^0.72.2","@effect-atom/atom":"^0.5.2","@aletso/effect-route":"^0.1.4"},"_npmOperationalInternal":{"tmp":"tmp/atom-query_0.1.5_1776788563579_0.8980854673131817","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@aletso/atom-query","version":"0.1.6","license":"MIT","_id":"@aletso/atom-query@0.1.6","maintainers":[{"name":"gbartman","email":"g.bartman@aletso.com"}],"dist":{"shasum":"1374d05383e3c1f5c50e94de27aad59d50177203","tarball":"https://registry.npmjs.org/@aletso/atom-query/-/atom-query-0.1.6.tgz","fileCount":27,"integrity":"sha512-xX7u6d/JMMCQvvZGc82/qqcPY+mk45/+p4dVUiUq7r2qYXz1ESS5lZmvZP9l6DGHE+pvV+XT0K2dhhf8Nk8Grw==","signatures":[{"sig":"MEYCIQCXaIvv1diVjF7Ostmd2uxn5WGf6Oi7B9pn3w6YP4gjAwIhAOqjAwnCL1BjH7/QtociddMWjaPIKjKkaoONQrv3/Tik","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113267},"type":"module","_from":"file:aletso-atom-query-0.1.6.tgz","exports":{"./*":"./dist/*.js"},"scripts":{"build":"tsc -b tsconfig.json","type-check":"tsc -b tsconfig.json"},"_npmUser":{"name":"gbartman","email":"g.bartman@aletso.com"},"_resolved":"/tmp/b360d7d4f5b4436b23816f8e8bd3345d/aletso-atom-query-0.1.6.tgz","_integrity":"sha512-xX7u6d/JMMCQvvZGc82/qqcPY+mk45/+p4dVUiUq7r2qYXz1ESS5lZmvZP9l6DGHE+pvV+XT0K2dhhf8Nk8Grw==","_npmVersion":"11.18.0","description":"Effect atom query layer with SWR, optimistic updates, and SSR preloading","directories":{},"_nodeVersion":"24.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@effect/language-service":"^0.62.3"},"peerDependencies":{"effect":"^3.19.12","@effect/rpc":"^0.72.2","@effect-atom/atom":"^0.5.2","@aletso/effect-route":"^0.1.4"},"_npmOperationalInternal":{"tmp":"tmp/atom-query_0.1.6_1783508188027_0.20025680063288398","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"@aletso/atom-query","version":"0.1.7","type":"module","description":"Effect atom query layer with SWR, optimistic updates, and SSR preloading","license":"MIT","exports":{"./*":"./dist/*.js"},"publishConfig":{"access":"public"},"peerDependencies":{"@effect-atom/atom":"^0.5.2","@effect/rpc":"^0.72.2","effect":"^3.19.12","@aletso/effect-route":"^0.1.4"},"devDependencies":{"@effect/language-service":"^0.62.3","typescript":"^5.9.3"},"scripts":{"build":"tsc -b tsconfig.json","type-check":"tsc -b tsconfig.json"},"_id":"@aletso/atom-query@0.1.7","_integrity":"sha512-Z5NZIxzH6FMotzegDZXQThauJ+IlQOHQkTG1tzJn1oLvfv8IYuVF3bz74/Uv6VgcxW2gvnimQT+PdsPE+UvZIQ==","_resolved":"/tmp/0d2abf38cd4cfd5c0b8fb54b87c4274c/aletso-atom-query-0.1.7.tgz","_from":"file:aletso-atom-query-0.1.7.tgz","_nodeVersion":"24.11.1","_npmVersion":"11.18.0","dist":{"integrity":"sha512-Z5NZIxzH6FMotzegDZXQThauJ+IlQOHQkTG1tzJn1oLvfv8IYuVF3bz74/Uv6VgcxW2gvnimQT+PdsPE+UvZIQ==","shasum":"867b53ef972a1922177e6805f196942c06d02d47","tarball":"https://registry.npmjs.org/@aletso/atom-query/-/atom-query-0.1.7.tgz","fileCount":27,"unpackedSize":111343,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEX2AeicDYNwDWo+YmaWRZIal3Gk7pqNoK1MPjLBj/KYAiEA3aPUxFeSj/qGpnhps43lvtvVQcr7PJDYlwuthlBQU4g="}]},"_npmUser":{"name":"gbartman","email":"g.bartman@aletso.com"},"directories":{},"maintainers":[{"name":"gbartman","email":"g.bartman@aletso.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/atom-query_0.1.7_1783511680603_0.163986075960334"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-14T17:59:14.321Z","modified":"2026-07-08T11:54:40.884Z","0.1.2":"2026-04-14T17:59:14.606Z","0.1.3":"2026-04-14T18:18:30.904Z","0.1.5":"2026-04-21T16:22:43.721Z","0.1.6":"2026-07-08T10:56:28.171Z","0.1.7":"2026-07-08T11:54:40.767Z"},"license":"MIT","description":"Effect atom query layer with SWR, optimistic updates, and SSR preloading","maintainers":[{"name":"gbartman","email":"g.bartman@aletso.com"}],"readme":"# @aletso/atom-query\n\nQuery and mutation primitives for Effect based apps that use route contracts from `@aletso/effect-route`.\n\nThis package is commonly used in layered data modules where:\n\n- `Route` and `RouteGroup` define API contracts\n- client data modules build query atoms and mutation triggers\n- server data modules build SSR preloaders\n- route loaders call `.ensure(...)` or `.prefetch(...)` on the right side (server or client)\n\n## Install\n\n```bash\npnpm add @aletso/atom-query @aletso/effect-route @effect-atom/atom @effect/rpc effect\n```\n\n## 1) Define contracts once with `@aletso/effect-route`\n\n```ts\nimport * as Route from \"@aletso/effect-route/Route\";\nimport * as RouteGroup from \"@aletso/effect-route/RouteGroup\";\nimport * as Schema from \"effect/Schema\";\n\nexport const SurveyListItem = Schema.Struct({\n  id: Schema.String,\n  title: Schema.String,\n});\n\nexport class SurveyNotFound extends Schema.TaggedError<SurveyNotFound>()(\n  \"SurveyNotFound\",\n  {\n    id: Schema.String,\n  },\n) {}\n\nexport class Group extends RouteGroup.make(\n  Route.make(\"find_many\", {\n    success: Schema.Array(SurveyListItem),\n  }),\n  Route.make(\"find_by_id\", {\n    success: SurveyListItem,\n    error: SurveyNotFound,\n    payload: Schema.Struct({ id: Schema.String }),\n  }),\n).prefix(\"survey_\") {}\n```\n\n## 2) Client data module\n\nExample client data module.\n\n```ts\nimport * as Atom from \"@effect-atom/atom/Atom\";\nimport * as Mutation from \"@aletso/atom-query/Mutation\";\nimport * as Query from \"@aletso/atom-query/Query\";\nimport * as Survey from \"../domain/api/Survey\";\nimport { SurveyApi } from \"../client/api/survey\";\nimport * as Effect from \"effect/Effect\";\n\nconst runtime = Atom.runtime(SurveyApi.Default);\n\nexport const surveyFindMany = Query.fromRoute(Survey.Group.find_many, {\n  effect: Effect.gen(function* () {\n    const api = yield* SurveyApi;\n    return yield* api.findMany();\n  }),\n  runtime,\n});\n\nexport const surveyFindById = Query.familyFromRoute(Survey.Group.find_by_id, {\n  effect: (payload) =>\n    Effect.gen(function* () {\n      const api = yield* SurveyApi;\n      return yield* api.findById(payload.id);\n    }),\n  runtime,\n});\n\nexport const surveyDelete = Mutation.fromRoute(Survey.Group.delete, {\n  effect: Effect.fnUntraced(function* (payload) {\n    const api = yield* SurveyApi;\n    return yield* api.delete(payload.id);\n  }),\n  runtime,\n});\n```\n\n## 3) Server data module for SSR preload\n\nExample server data module for SSR preloading.\n\n```ts\nimport * as Query from \"@aletso/atom-query/Query\";\nimport * as Survey from \"../domain/api/Survey\";\nimport { SurveyService } from \"../server/public/survey/service\";\nimport * as Effect from \"effect/Effect\";\n\nexport const surveyFindManyServer = Query.serverFromRoute(\n  Survey.Group.find_many,\n  {\n    effect: Effect.flatMap(SurveyService, (s) => s.findMany),\n  },\n);\n\nexport const surveyFindByIdServer = Query.serverFamilyFromRoute(\n  Survey.Group.find_by_id,\n  {\n    effect: (payload) =>\n      Effect.flatMap(SurveyService, (s) => s.findById(payload.id)),\n  },\n);\n```\n\n## 4) Isomorphic route loaders with `.ensure(...)` and `.prefetch(...)`\n\nExample isomorphic loader usage.\n\n```ts\nimport { createIsomorphicFn } from \"@tanstack/react-start\";\nimport {\n  surveyFindById,\n  surveyFindByIdServer,\n  surveyFindManyServer,\n} from \"../data/survey\";\nimport { serverRuntime } from \"../routes/api/rpc/$\";\n\nexport const ensureSurvey = createIsomorphicFn()\n  .server((context, id: string) =>\n    surveyFindByIdServer.ensure(context.registry, serverRuntime, { id }),\n  )\n  .client((context, id: string) =>\n    surveyFindById.ensure(context.registry, { id }),\n  );\n\nexport const prefetchSurveyList = createIsomorphicFn().server((context) =>\n  surveyFindManyServer.prefetch(context.registry, serverRuntime),\n);\n```\n\n## 5) SWR and optimistic cache updates\n\nExample optimistic cache update flow.\n\n```ts\nimport { Atom } from \"@effect-atom/atom-react\";\nimport * as Query from \"@aletso/atom-query/Query\";\nimport * as Arr from \"effect/Array\";\nimport * as Data from \"effect/Data\";\nimport * as Option from \"effect/Option\";\n\ntype Survey = { id: string; title: string };\n\nexport type SurveyCacheUpdate = Data.TaggedEnum<{\n  Delete: { readonly id: string };\n  Upsert: { readonly item: Survey };\n}>;\n\nconst remoteAtom = surveyFindMany.pipe(Atom.setIdleTTL(0));\n\nexport const surveyList = Query.lazyOptimistic(\n  remoteAtom,\n  (current, update: SurveyCacheUpdate) => {\n    switch (update._tag) {\n      case \"Delete\":\n        return Arr.filter(current, (s) => s.id !== update.id);\n      case \"Upsert\": {\n        const index = Arr.findFirstIndex(\n          current,\n          (s) => s.id === update.item.id,\n        );\n        return Option.match(index, {\n          onNone: () => Arr.prepend(current, update.item),\n          onSome: (i) => Arr.replace(current, i, update.item),\n        });\n      }\n    }\n  },\n).pipe(Atom.setIdleTTL(300_000), Query.swr({ staleTime: 60_000 }));\n\n// Force next read to revalidate\nsurveyList.invalidate();\n```\n\n## 6) Request header propagation for middleware aware queries\n\n`CurrentHeaders` lets server queries read headers from effect context when explicit headers are not passed.\n\n```ts\nimport { CurrentHeaders } from \"@aletso/atom-query/RequestHeaders\";\nimport * as Effect from \"effect/Effect\";\nimport * as ManagedRuntime from \"effect/ManagedRuntime\";\nimport { getRequestHeaders } from \"@tanstack/react-start/server\";\n\nconst makeServerRuntime = (layer: any, memoMap: any) => {\n  const raw = ManagedRuntime.make(layer, memoMap);\n  return new Proxy(raw, {\n    get(target, prop) {\n      const value = Reflect.get(target, prop, target);\n      if (\n        (prop === \"runPromise\" || prop === \"runPromiseExit\") &&\n        typeof value === \"function\"\n      ) {\n        return (\n          effect: Effect.Effect<any, any, any>,\n          ...rest: ReadonlyArray<any>\n        ) => {\n          let headers: Record<string, string> = {};\n          try {\n            headers = getRequestHeaders() ?? {};\n          } catch {\n            headers = {};\n          }\n          return value.call(\n            target,\n            Effect.provideService(effect, CurrentHeaders, headers),\n            ...rest,\n          );\n        };\n      }\n      return typeof value === \"function\" ? value.bind(target) : value;\n    },\n  });\n};\n```\n\n## API surface\n\n- `Query.fromRoute`, `Query.familyFromRoute`\n- `Query.serverFromRoute`, `Query.serverFamilyFromRoute`\n- `Query.swr`, `Query.lazyOptimistic`\n- `Mutation.fromRoute`\n- `RequestHeaders.CurrentHeaders`\n","readmeFilename":"README.md"}