{"_id":"@atmosstacks/atmos-sdk","name":"@atmosstacks/atmos-sdk","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.1":{"name":"@atmosstacks/atmos-sdk","version":"0.1.1","type":"module","main":"dist/index.cjs","module":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test":"vitest run --config vitest.config.ts","test:watch":"vitest --config vitest.config.ts","test:ci":"vitest run --config vitest.config.ts --reporter=verbose","test:coverage":"vitest run --config vitest.config.ts --coverage"},"dependencies":{"@stacks/connect":"^7.10.2","@stacks/transactions":"^7.3.1"},"devDependencies":{"typescript":"^5.5.4","@vitest/coverage-v8":"^2.1.9","vitest":"^2.1.1"},"publishConfig":{"access":"public"},"_id":"@atmosstacks/atmos-sdk@0.1.1","gitHead":"bd45ad625a1257a395399f3d240ec6620e9d3656","description":"TypeScript SDK for uploading, downloading, verifying, and previewing datasets.","_nodeVersion":"24.2.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-IeQ0W7E/Vags/6/Nx4pBfauov4jLkcezE+pec5EAksu2WFzXALve0SXA0do/jLlKjeFiX27nyBXvXSGw+S8Y4g==","shasum":"be5ddd5d6c909d38b49aabfab904408bdd89a29f","tarball":"https://registry.npmjs.org/@atmosstacks/atmos-sdk/-/atmos-sdk-0.1.1.tgz","fileCount":48,"unpackedSize":82015,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDiXnr+1ouyaKkX2HFkEf/SC2EX7U7Ig9x8CBE7cKgMRgIgA9Gu+lWqR/GzLlZ6Ac6fgstdkngyStbgkrgkLCUhIbw="}]},"_npmUser":{"name":"sukanto","email":"sukanto01899@gmail.com"},"directories":{},"maintainers":[{"name":"sukanto","email":"sukanto01899@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/atmos-sdk_0.1.1_1775599451456_0.12817803405555672"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-07T22:04:11.391Z","0.1.1":"2026-04-07T22:04:11.626Z","modified":"2026-04-07T22:04:12.016Z"},"maintainers":[{"name":"sukanto","email":"sukanto01899@gmail.com"}],"description":"TypeScript SDK for uploading, downloading, verifying, and previewing datasets.","readme":"# Atmos SDK\n\nTypeScript SDK for uploading, downloading, verifying, and previewing datasets.\n\n## Features\n\n- Upload with resumable sessions\n- Download with streaming or range reads\n- Preview data and inspect schema\n- Verify integrity hashes\n\n## Install\n\n```bash\nnpm install @sukanto01899/atmos-sdk\n```\n\n## Quick start\n\n```ts\nimport { SdkClient, createIpfsAdapter } from \"@sukanto01899/atmos-sdk\";\n\nconst client = new SdkClient({\n  baseUrl: \"https://api.atmos.example\",\n  storage: createIpfsAdapter({\n    endpoint: \"https://ipfs.example\",\n    pin: true,\n  }),\n});\n\nconst metadata = {\n  name: \"Gulf Stream Snapshot\",\n  description: \"Surface temperature tiles for 2026-01-15.\",\n  dataType: \"imagery\",\n  isPublic: true,\n  collectionDate: 1764768000,\n  altitudeMin: 0,\n  altitudeMax: 0,\n  latitude: 26.1,\n  longitude: -79.9,\n};\n\nconst file = new Blob([\"lat,lon,temp\\n26.1,-79.9,26.2\\n\"], {\n  type: \"text/csv\",\n});\n\nconst upload = await client.upload(file, { metadata });\nconsole.log(upload.id, upload.location);\n```\n\n## Common tasks\n\n### Upload (resumable)\n\n```ts\nconst result = await client.upload(file, {\n  metadata,\n  resumable: true,\n  chunkSize: 5 * 1024 * 1024,\n  onProgress: ({ uploadedBytes, totalBytes, percent }) => {\n    console.log(uploadedBytes, totalBytes, percent);\n  },\n});\n```\n\n### Batch upload\n\n```ts\nconst batch = await client.uploadBatch(\n  [\n    { data: fileA, options: { metadata: metaA } },\n    { data: fileB, options: { metadata: metaB } },\n  ],\n  {\n    concurrency: 3,\n    retries: 2,\n    retryDelayMs: 400,\n    stopOnError: false,\n    onProgress: (progress) => console.log(progress),\n  },\n);\n\nconst successes = batch.filter((item) => item.status === \"fulfilled\");\nconst failures = batch.filter((item) => item.status === \"rejected\");\n```\n\n### Upload bundle (multi-file)\n\nUploads a directory CID containing your files plus `manifest.json` with per-file SHA-256 checksums.\n\n```ts\nconst bundle = await client.uploadBundle({\n  metadata,\n  files: [\n    { path: \"data/part-001.csv\", data: fileA },\n    { path: \"data/part-002.csv\", data: fileB },\n  ],\n});\n\nconsole.log(bundle.id); // directory CID\n```\n\n### Download bundle manifest / file\n\n```ts\nconst manifest = await client.downloadBundleManifest(bundle.id);\nconst { data } = await client.downloadBundleFile(bundle.id, \"data/part-001.csv\");\n```\n\n### Download\n\n```ts\nconst { data } = await client.download(\"QmHash\");\nif (data) {\n  const text = new TextDecoder().decode(data);\n  console.log(text);\n}\n```\n\n### Download (stream)\n\n```ts\nconst { stream } = await client.download(\"QmHash\", { asStream: true });\nif (stream) {\n  const reader = stream.getReader();\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    console.log(value.byteLength);\n  }\n}\n```\n\n### Batch download\n\n```ts\nconst results = await client.downloadBatch(\n  [{ id: \"QmA\" }, { id: \"QmB\" }],\n  { concurrency: 4 },\n);\n```\n\n### Preview\n\n```ts\nconst preview = await client.preview(\"QmHash\", { maxRows: 5, format: \"csv\" });\nconsole.table(preview.rows);\n```\n\nPreview now returns `schema` when available (CSV/JSON/NDJSON auto-detect).\n\n### Verify\n\n```ts\nconst result = await client.verify(\"QmHash\", {\n  checksum: \"ab12...ef\",\n  sizeBytes: 1024,\n});\nconsole.log(result.ok, result.reason);\n```\n\n### Publish (upload + checksum + register)\n\n```ts\nimport {\n  SdkClient,\n  httpTransport,\n  createHttpRegistry,\n  createStacksOnChainPublisher,\n} from \"@sukanto01899/atmos-sdk\";\n\nconst baseUrl = \"https://api.atmos.example\";\nconst transport = httpTransport({ baseUrl });\n\nconst client = new SdkClient({\n  baseUrl,\n  transport,\n  storage,\n  registry: createHttpRegistry(transport),\n  onchain: createStacksOnChainPublisher({ contractAddress: \"SP…\", contractName: \"atmos-v4\" }),\n});\n\nconst published = await client.publish({\n  kind: \"file\",\n  data: file,\n  metadata,\n  target: \"both\",\n  broadcastOnChainTx: false, // for wallet flow, use createStacksConnectOnChainPublisher(...)\n});\n```\n\n## Listing datasets (pagination)\n\n```ts\nconst page1 = await client.listDatasets({\n  limit: 25,\n  cursor: \"0\",\n  sort: \"created_at_desc\",\n  tags: [\"wind\", \"hourly\"],\n});\nconst page2 = page1.nextCursor\n  ? await client.listDatasets({ limit: 25, cursor: page1.nextCursor, sort: \"created_at_desc\" })\n  : null;\n```\n\n## Listing tags\n\n```ts\nconst tags = await client.listTags({ isPublic: true });\nconsole.table(tags.items);\n```\n\n## Authentication\n\n```ts\nconst client = new SdkClient({\n  baseUrl: \"https://api.atmos.example\",\n  auth: {\n    getAccessToken: async () => \"token\",\n  },\n});\n```\n\n## Storage adapters\n\n### IPFS\n\n```ts\nimport { createIpfsAdapter } from \"@sukanto01899/atmos-sdk\";\n\nconst storage = createIpfsAdapter({\n  endpoint: \"https://ipfs.example\",\n  headers: {\n    authorization: \"Basic ...\",\n  },\n  pin: true,\n  timeoutMs: 30_000,\n  cidVersion: 1,\n  cidBase: \"base32\",\n  mfsRoot: \"/atmos\",\n});\n```\n\n### S3\n\n```ts\nimport { createS3Adapter } from \"@sukanto01899/atmos-sdk\";\n\nconst storage = createS3Adapter({\n  bucket: \"atmos-datasets\",\n  region: \"us-east-1\",\n});\n```\n\n## Errors\n\nAll SDK errors throw `SdkError` with `code`, `message`, and optional `status`.\n\n```ts\nimport { SdkError } from \"@sukanto01899/atmos-sdk\";\n\ntry {\n  await client.download(\"bad-id\");\n} catch (error) {\n  if (error instanceof SdkError) {\n    console.error(error.code, error.status, error.message);\n  }\n}\n```\n\n## Environment notes\n\n- Browser: `Blob` and `ReadableStream` are available.\n- Node.js: use `undici` or a fetch polyfill if needed.\n\n## API reference\n\nSee `docs/API.md` for the full API surface.\n\r\n","readmeFilename":"README.md","_rev":"1-f26f6781a2b71f0575f70bfbaf5447a5"}