{"_id":"@duran.ai/tsetsen","_rev":"9-934e9acdd68fdae5a0f1d8f7aede335d","name":"@duran.ai/tsetsen","dist-tags":{"latest":"0.1.10"},"versions":{"0.1.1":{"name":"@duran.ai/tsetsen","version":"0.1.1","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","_id":"@duran.ai/tsetsen@0.1.1","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"dist":{"shasum":"b04bdd8e6352322cd53c4d4b970994066dd085ae","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.1.tgz","fileCount":27,"integrity":"sha512-WrTxXy3lwx6MIOq5AVv2SQULClb2OU6TcO2qAAy5euVAhk9u5x8JzMa2BKA+AKoPwXUI5LWxqeW3ifwK9lRLKw==","signatures":[{"sig":"MEQCIDtGKFD9kALVsBj5VWEWJ7DOZcpX83A/WdPVXFNLvpHTAiBMVpO2sefFI5yG7b7FdGz0QMCp+px3q0pLYbtbGaKuug==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94177},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"scripts":{"docs":"typedoc --out docs src/index.ts","lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","clean":"rimraf dist","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build","proto:generate":"node scripts/generate-proto.js"},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"repository":{"url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git","type":"git"},"_npmVersion":"10.8.1","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","directories":{"test":"test","example":"examples"},"_nodeVersion":"20.16.0","dependencies":{"@grpc/grpc-js":"^1.13.3","google-protobuf":"^3.21.4","@grpc/proto-loader":"^0.7.15"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","prettier":"^3.5.3","grpc-tools":"^1.13.0","typescript":"^5.1.6","@types/jest":"^29.5.14","@types/node":"^18.19.86","@types/google-protobuf":"^3.15.12","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","@typescript-eslint/parser":"^6.21.0","grpc_tools_node_protoc_ts":"^5.3.3","@typescript-eslint/eslint-plugin":"^6.21.0"},"_npmOperationalInternal":{"tmp":"tmp/tsetsen_0.1.1_1745467958726_0.1669225639856433","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@duran.ai/tsetsen","version":"0.1.2","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","_id":"@duran.ai/tsetsen@0.1.2","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"dist":{"shasum":"f40daf6a1fafcbc15fc3fcc8cca2699dcd50be8b","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.2.tgz","fileCount":27,"integrity":"sha512-8lcPGjiVoHlNvYvrv5dNUCfDStpI3DZmX+FLjA7m0FH0+HUtvNaXUh3wllK0tcGjQHnI2rmLTcFowavUxmLDfg==","signatures":[{"sig":"MEQCIDOmfs9hjDS9Ow9XhYNC3wPsTSiDlr90WYeLc7nQYM/5AiAp2F0+gCIgVUSk2wuuFdOHGKE4kHhaFYfIKg0J+UTn6Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94226},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"scripts":{"docs":"typedoc --out docs src/index.ts","lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","clean":"rimraf dist","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build","proto:generate":"node scripts/generate-proto.js"},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"repository":{"url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git","type":"git"},"_npmVersion":"10.8.1","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","directories":{"test":"test","example":"examples"},"_nodeVersion":"20.16.0","dependencies":{"@grpc/grpc-js":"^1.13.3","google-protobuf":"^3.21.4","@grpc/proto-loader":"^0.7.15"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","prettier":"^3.5.3","grpc-tools":"^1.13.0","typescript":"^5.1.6","@types/jest":"^29.5.14","@types/node":"^18.19.86","@types/google-protobuf":"^3.15.12","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","@typescript-eslint/parser":"^6.21.0","grpc_tools_node_protoc_ts":"^5.3.3","@typescript-eslint/eslint-plugin":"^6.21.0"},"_npmOperationalInternal":{"tmp":"tmp/tsetsen_0.1.2_1745468146730_0.28859754465311704","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@duran.ai/tsetsen","version":"0.1.3","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","_id":"@duran.ai/tsetsen@0.1.3","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"dist":{"shasum":"956592e40d0cb85f6546f3ea7a362cffde9774d0","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.3.tgz","fileCount":28,"integrity":"sha512-iNEYMxqSgP7fOZo57Zr+7ZAC+fCyltcrlFjpL6xUrEtjHmJO0IXKsXl9W3+atgs1kmnAlMYVnpnF4PdYoJG4Rg==","signatures":[{"sig":"MEUCIG433Jxn/SM2WCodCYPNC5cx8HrpSUa1xDiB1VwaqKGfAiEAhK2rzaYC7aXj56Irvvf/zZmcRfIuA4w6UmLiAAXaX+g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":97270},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"scripts":{"docs":"typedoc --out docs src/index.ts","lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","clean":"rimraf dist","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build","proto:generate":"node scripts/generate-proto.js"},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"repository":{"url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git","type":"git"},"_npmVersion":"10.8.1","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","directories":{"test":"test","example":"examples"},"_nodeVersion":"20.16.0","dependencies":{"@grpc/grpc-js":"^1.13.3","google-protobuf":"^3.21.4","@grpc/proto-loader":"^0.7.15"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","prettier":"^3.5.3","grpc-tools":"^1.13.0","typescript":"^5.1.6","@types/jest":"^29.5.14","@types/node":"^18.19.86","@types/google-protobuf":"^3.15.12","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","@typescript-eslint/parser":"^6.21.0","grpc_tools_node_protoc_ts":"^5.3.3","@typescript-eslint/eslint-plugin":"^6.21.0"},"_npmOperationalInternal":{"tmp":"tmp/tsetsen_0.1.3_1745468354130_0.28535959469336514","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@duran.ai/tsetsen","version":"0.1.4","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","_id":"@duran.ai/tsetsen@0.1.4","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"dist":{"shasum":"4d8f632fe86cc21185177022229d4e18eaab7d54","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.4.tgz","fileCount":28,"integrity":"sha512-JxhAy1Dt1d1147qrIB+UEG7VdP69taAyJBoAuX0Ysn8rCWuDceFyPHV5h5sJgBxGfDv1ATXPPfexPFTHaBm4MA==","signatures":[{"sig":"MEUCIQD31i4IH03H9yVXN1Jr0NoS3jDnLGyr/f14Fs6m6oT5VAIgEsedM4Ix7ArGBiyUD1hfE4FXC8AiFxEiM38Y6DbqdOk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":101549},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"scripts":{"docs":"typedoc --out docs src/index.ts","lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","clean":"rimraf dist","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build","proto:generate":"node scripts/generate-proto.js"},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"repository":{"url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git","type":"git"},"_npmVersion":"10.8.1","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","directories":{"test":"test","example":"examples"},"_nodeVersion":"20.16.0","dependencies":{"@grpc/grpc-js":"^1.13.3","google-protobuf":"^3.21.4","@grpc/proto-loader":"^0.7.15"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","prettier":"^3.5.3","grpc-tools":"^1.13.0","typescript":"^5.1.6","@types/jest":"^29.5.14","@types/node":"^18.19.86","@types/google-protobuf":"^3.15.12","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","@typescript-eslint/parser":"^6.21.0","grpc_tools_node_protoc_ts":"^5.3.3","@typescript-eslint/eslint-plugin":"^6.21.0"},"_npmOperationalInternal":{"tmp":"tmp/tsetsen_0.1.4_1745468707231_0.15286693996802647","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@duran.ai/tsetsen","version":"0.1.5","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","_id":"@duran.ai/tsetsen@0.1.5","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"dist":{"shasum":"758bd98cf2a6b2b0fa5e5504d6d9d2d1d563e14e","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.5.tgz","fileCount":28,"integrity":"sha512-rZbeK9B9LUNY+ZgxWkxHbD2uCgebzPfJw1pl4e0zt6PXVUcpM0XiBe03WNDEkiFS0snnSpupIA5RNWLRXKARVg==","signatures":[{"sig":"MEUCIQDa67nykULAuYvoeL2hIHcBh2ROrcnHJ0HFeiRR86icnQIgAOjHRA0K90VnKjHaU2+XmWpdY/VDYNdrZK841SnXUcs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":103030},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"scripts":{"docs":"typedoc --out docs src/index.ts","lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","clean":"rimraf dist","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build","proto:generate":"node scripts/generate-proto.js"},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"repository":{"url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git","type":"git"},"_npmVersion":"10.8.1","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","directories":{"test":"test","example":"examples"},"_nodeVersion":"20.16.0","dependencies":{"@grpc/grpc-js":"^1.13.3","google-protobuf":"^3.21.4","@grpc/proto-loader":"^0.7.15"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","prettier":"^3.5.3","grpc-tools":"^1.13.0","typescript":"^5.1.6","@types/jest":"^29.5.14","@types/node":"^18.19.86","@types/google-protobuf":"^3.15.12","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","@typescript-eslint/parser":"^6.21.0","grpc_tools_node_protoc_ts":"^5.3.3","@typescript-eslint/eslint-plugin":"^6.21.0"},"_npmOperationalInternal":{"tmp":"tmp/tsetsen_0.1.5_1745469072469_0.24649079277429076","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@duran.ai/tsetsen","version":"0.1.6","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","_id":"@duran.ai/tsetsen@0.1.6","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"dist":{"shasum":"159ec954826a0e4a8ba5fdc283f631647d992903","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.6.tgz","fileCount":28,"integrity":"sha512-BhjrpmzdGK8aEb2j+ZqTxLCWqKMJpysSiefDBZs1tekQZLPiKVuD8PodGEDkJr1XpIzBZ500tTpDQW0z4VRzew==","signatures":[{"sig":"MEYCIQCqHize4Ro/+CKffIT04IGEOzhq4IGjZvkiUxjuhpzUWgIhANkL7jEhh/sehZD4zQZYsGIRuOPW2kZoir3gPUfvAXOb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105343},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"scripts":{"docs":"typedoc --out docs src/index.ts","lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","clean":"rimraf dist","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build","proto:generate":"node scripts/generate-proto.js"},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"repository":{"url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git","type":"git"},"_npmVersion":"10.8.1","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","directories":{"test":"test","example":"examples"},"_nodeVersion":"20.16.0","dependencies":{"@grpc/grpc-js":"^1.13.3","google-protobuf":"^3.21.4","@grpc/proto-loader":"^0.7.15"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","prettier":"^3.5.3","grpc-tools":"^1.13.0","typescript":"^5.1.6","@types/jest":"^29.5.14","@types/node":"^18.19.86","@types/google-protobuf":"^3.15.12","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","@typescript-eslint/parser":"^6.21.0","grpc_tools_node_protoc_ts":"^5.3.3","@typescript-eslint/eslint-plugin":"^6.21.0"},"_npmOperationalInternal":{"tmp":"tmp/tsetsen_0.1.6_1745469288848_0.7135567403689218","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"@duran.ai/tsetsen","version":"0.1.7","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","_id":"@duran.ai/tsetsen@0.1.7","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"dist":{"shasum":"66531487517e071a7da99f19374ebce5c5160bc3","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.7.tgz","fileCount":28,"integrity":"sha512-QaxYsc5Gta3rZisAqVSHjSXvwZSyPGWwnhk5bS6WzrCDrZ56ZXqTf01RIWfFREeauBmPPC4SueX7ducUVpDGwQ==","signatures":[{"sig":"MEQCIFPba3Pp/abqFJtdwnjCU51rp5kmwtKBKSrxtVvOyRObAiAiM86KPB86GsFPgJouinEJSjvMp0eK1phUCp3thAstaQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107460},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"scripts":{"docs":"typedoc --out docs src/index.ts","lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","clean":"rimraf dist","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build","proto:generate":"node scripts/generate-proto.js"},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"repository":{"url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git","type":"git"},"_npmVersion":"10.8.1","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","directories":{"test":"test","example":"examples"},"_nodeVersion":"20.16.0","dependencies":{"@grpc/grpc-js":"^1.13.3","google-protobuf":"^3.21.4","@grpc/proto-loader":"^0.7.15"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","prettier":"^3.5.3","grpc-tools":"^1.13.0","typescript":"^5.1.6","@types/jest":"^29.5.14","@types/node":"^18.19.86","@types/google-protobuf":"^3.15.12","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","@typescript-eslint/parser":"^6.21.0","grpc_tools_node_protoc_ts":"^5.3.3","@typescript-eslint/eslint-plugin":"^6.21.0"},"_npmOperationalInternal":{"tmp":"tmp/tsetsen_0.1.7_1745469583484_0.45731686571130736","host":"s3://npm-registry-packages-npm-production"}},"0.1.8":{"name":"@duran.ai/tsetsen","version":"0.1.8","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","_id":"@duran.ai/tsetsen@0.1.8","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"dist":{"shasum":"ad4a5ea939734b491d71b29bc84d7b9afda6c42f","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.8.tgz","fileCount":28,"integrity":"sha512-53ne+Nn7LiHN5UaiBqGjPlqSQl2oEmnfp/Q6Ua5N3TBt0ByjN+DNjRDiCpdyPRYAZdbfyXDpEr6r+d+/WBnJdA==","signatures":[{"sig":"MEYCIQC0dsBBwB/zoKWUt+ZOYLhPKO1/wcz+Cw9NKPCqk8irBAIhAK0WdIT9o7jk8zLdgoPH32LH7rJ1EDO04xvRPjqgpn4R","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":109300},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"scripts":{"docs":"typedoc --out docs src/index.ts","lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","clean":"rimraf dist","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run build","proto:generate":"node scripts/generate-proto.js"},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"repository":{"url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git","type":"git"},"_npmVersion":"10.8.1","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","directories":{"test":"test","example":"examples"},"_nodeVersion":"20.16.0","dependencies":{"@grpc/grpc-js":"^1.13.3","google-protobuf":"^3.21.4","@grpc/proto-loader":"^0.7.15"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","prettier":"^3.5.3","grpc-tools":"^1.13.0","typescript":"^5.1.6","@types/jest":"^29.5.14","@types/node":"^18.19.86","@types/google-protobuf":"^3.15.12","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","@typescript-eslint/parser":"^6.21.0","grpc_tools_node_protoc_ts":"^5.3.3","@typescript-eslint/eslint-plugin":"^6.21.0"},"_npmOperationalInternal":{"tmp":"tmp/tsetsen_0.1.8_1745469851894_0.8458191941369029","host":"s3://npm-registry-packages-npm-production"}},"0.1.10":{"name":"@duran.ai/tsetsen","version":"0.1.10","description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"clean":"rimraf dist","build":"npm run clean && npm run proto:generate && tsc -p tsconfig.build.json","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","lint":"eslint . --ext .ts","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","proto:generate":"node scripts/generate-proto.js","prepublishOnly":"npm run build","docs":"typedoc --out docs src/index.ts","release:patch":"npm run build && npm version patch && npm publish --access public","release:minor":"npm run build && npm version minor && npm publish --access public","release:major":"npm run build && npm version major && npm publish --access public"},"keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git"},"bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","dependencies":{"@grpc/grpc-js":"^1.13.3","@grpc/proto-loader":"^0.7.15","google-protobuf":"^3.21.4"},"devDependencies":{"@types/google-protobuf":"^3.15.12","@types/jest":"^29.5.14","@types/node":"^18.19.86","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","eslint":"^8.57.1","eslint-config-prettier":"^8.10.0","eslint-plugin-prettier":"^5.2.6","grpc_tools_node_protoc_ts":"^5.3.3","grpc-tools":"^1.13.0","jest":"^29.7.0","prettier":"^3.5.3","rimraf":"^5.0.10","ts-jest":"^29.3.2","ts-node":"^10.9.2","typedoc":"^0.24.8","typescript":"^5.1.6"},"engines":{"node":">=14.0.0"},"directories":{"example":"examples","test":"test"},"_id":"@duran.ai/tsetsen@0.1.10","gitHead":"14c7cdd30391c90ad212d641ecf1ec16ffcdbc7f","_nodeVersion":"20.16.0","_npmVersion":"10.8.1","dist":{"integrity":"sha512-fRqDh2Si+4gCsXfIHAjWxdlvh9tX0B1rZqYH1homIBHKLwa9nbJxwZnUn5d97Qpyl6rv5+AuTFMeby1Cp2gbPw==","shasum":"714e5bdaeaafee1c6d3814e9ed12d6bfbb57ccd5","tarball":"https://registry.npmjs.org/@duran.ai/tsetsen/-/tsetsen-0.1.10.tgz","fileCount":28,"unpackedSize":132936,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGmmR6O0hk+2YoF1sQuSzrvKstkjEor7Cc7vx6gUpyQxAiB4dKjqvp7UAEiBEs4XxvjrlBF5xW5DQ5Q7mAYZxRS/Sg=="}]},"_npmUser":{"name":"nomad.amaraa","email":"amar@duran.ai"},"maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tsetsen_0.1.10_1746665940580_0.3062053696417022"},"_hasShrinkwrap":false}},"time":{"created":"2025-04-24T04:12:38.599Z","modified":"2025-05-08T00:59:00.986Z","0.1.1":"2025-04-24T04:12:38.905Z","0.1.2":"2025-04-24T04:15:46.901Z","0.1.3":"2025-04-24T04:19:14.413Z","0.1.4":"2025-04-24T04:25:07.465Z","0.1.5":"2025-04-24T04:31:12.696Z","0.1.6":"2025-04-24T04:34:49.110Z","0.1.7":"2025-04-24T04:39:43.692Z","0.1.8":"2025-04-24T04:44:12.137Z","0.1.10":"2025-05-08T00:59:00.767Z"},"bugs":{"url":"https://github.com/tsetsen-ai/tsetsen-node-sdk/issues"},"author":{"name":"Amar Amarsanaa @ duran.ai"},"license":"MIT","homepage":"https://github.com/tsetsen-ai/tsetsen-node-sdk#readme","keywords":["tts","text-to-speech","speech synthesis","voice","ai","grpc","tsetsen"],"repository":{"type":"git","url":"git+https://github.com/tsetsen-ai/tsetsen-node-sdk.git"},"description":"Node.js SDK for the Tsetsen, Mongolian Text-to-Speech API","maintainers":[{"name":"nomad.amaraa","email":"amar@duran.ai"}],"readme":"# Tsetsen TTS Node.js SDK\n\nA Node.js SDK for the Tsetsen Text-to-Speech API, providing a simple interface for generating high-quality Mongolian speech from text.\n\n*[Монгол хэл дээрх гарын авлагыг доор харна уу.](#монгол-хэл-дээрх-гарын-авлага)*\n\n## Installation\n\n```bash\nnpm i @duran.ai/tsetsen\n```\n\n## Prerequisites\n\n- Node.js 14.x or higher\n- A Tsetsen API key (sign up at [developer.tsetsen.ai](https://developer.tsetsen.ai))\n\n## Quick Start\n\n```typescript\nimport { Client, RequestStatus } from '@duran.ai/tsetsen';\n\n// Initialize the client with your API key\nconst client = new Client({\n  apiKey: 'your-api-key',\n  // Optional: Specify a timeout for requests\n  timeout: 60000, // 60 seconds\n});\n\nasync function main() {\n  try {\n    // List available Mongolian voices\n    const voicesResponse = await client.listVoices({ version: 'beta-v0.1' });\n    console.log(`Available Mongolian voices: ${voicesResponse.voices.length}`);\n    \n    // Select a voice to use\n    const selectedVoice = voicesResponse.voices[0];\n    console.log(`Using voice: ${selectedVoice.name} (${selectedVoice.id})`);\n    \n    // Generate Mongolian speech\n    const response = await client.generateSpeech({\n      text: 'Сайн байна уу! Би Цэцэн хиймэл оюун ухаан системийн дуу хоолой.',\n      voiceId: selectedVoice.id,\n      version: 'beta-v0.1'\n    });\n    console.log(`Generation request submitted: ${response.requestId}`);\n    \n    // Wait for completion with proper error handling\n    try {\n      const result = await client.waitForCompletion(response.requestId, {\n        timeout: 120000,      // 2 minutes timeout for longer texts\n        pollInterval: 1000    // Check every second\n      });\n      \n      if (result.status === RequestStatus.COMPLETED) {\n        console.log(`Audio URL: ${result.audioUrl}`);\n        \n        // Display metrics if available\n        if (result.metrics) {\n          console.log(`Audio length: ${result.metrics.audioLength} seconds`);\n          console.log(`Processing time: ${result.metrics.processingTime} ms`);\n          console.log(`Credits used: ${result.metrics.creditsUsed}`);\n        }\n      } else {\n        console.log(`Generation failed: ${result.errorMessage}`);\n      }\n    } catch (error) {\n      if (error.code === 'timeout') {\n        console.error('Request timed out. The operation might still complete on the server.');\n      } else {\n        throw error; // rethrow other errors\n      }\n    }\n  } catch (error) {\n    console.error('Error:', error.message);\n    // Handle specific error types\n    if (error.code) {\n      console.error(`Error code: ${error.code}`);\n    }\n  } finally {\n    // Always close the client when done\n    client.close();\n  }\n}\n\nmain();\n```\n\n## Streaming Speech\n\nIn addition to the asynchronous speech generation with `generateSpeech`, the SDK now supports real-time streaming of speech using `streamSpeech`. This allows you to receive and process audio chunks as they are generated, without waiting for the entire audio to be processed.\n\n### Streaming Limitations\n\n- Streaming is only supported with the `beta-v0.2` model version\n- Rate limit: 1 request per minute (free tier)\n- Maximum streaming duration: 5 minutes\n- Audio format: 24,000Hz, 16-bit, mono\n\n### Basic Streaming Example\n\n```typescript\nimport { Client, RequestStatus } from '@duran.ai/tsetsen';\nimport * as fs from 'fs';\n\n// Initialize the client\nconst client = new Client({\n  apiKey: 'your-api-key' \n});\n\n// Stream speech with callbacks\nconst streamController = client.streamSpeech({\n  text: 'Сайн байна уу! Энэ бол Цэцэн дуу хоолойны шууд урсгал юм.',\n  voiceId: 'voice-id',\n  version: 'beta-v0.2', // Required for streaming\n  \n  // Receive audio chunks as they arrive\n  onData: (audioChunk, isFinal) => {\n    console.log(`Received chunk: ${audioChunk.length} bytes, final: ${isFinal}`);\n    \n    // Process audio chunks in real-time\n    // For example, you could send to a WebSocket, play it, etc.\n  },\n  \n  // Called when streaming is complete\n  onComplete: () => {\n    console.log('Streaming completed successfully');\n    client.close();\n  },\n  \n  // Called if an error occurs\n  onError: (error) => {\n    console.error('Streaming error:', error);\n    client.close();\n  }\n});\n\n// You can cancel the stream at any time\n// streamController.cancel();\n```\n\n### Saving Stream to File\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\n\n// Initialize the client\nconst client = new Client({\n  apiKey: 'your-api-key'\n});\n\n// Stream speech directly to a file\nconst streamController = client.streamSpeech({\n  text: 'Сайн байна уу! Энэ бол Цэцэн дуу хоолойны шууд урсгал юм.',\n  voiceId: 'voice-id',\n  outputFile: 'output.raw', // Save to file (raw 16-bit PCM format)\n  \n  onComplete: () => {\n    console.log('Audio saved to output.raw');\n    client.close();\n  },\n  \n  onError: (error) => {\n    console.error('Error:', error);\n    client.close();\n  }\n});\n```\n\n### Playing Audio in Real-time\n\nTo play the audio in real-time, you can use an audio library like `speaker` or `node-aplay`. Here's an example using the `speaker` package:\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\nimport Speaker from 'speaker';\n\n// Install with: npm install speaker\n\n// Initialize the client\nconst client = new Client({\n  apiKey: 'your-api-key'\n});\n\n// Set up the speaker\nconst speaker = new Speaker({\n  channels: 1,          // mono\n  bitDepth: 16,         // 16-bit samples\n  sampleRate: 24000,    // 24,000 Hz sample rate\n  signed: true          // signed data (true for PCM16)\n});\n\n// Stream speech directly to the speaker\nconst streamController = client.streamSpeech({\n  text: 'Сайн байна уу! Энэ бол Цэцэн дуу хоолойны шууд урсгал юм.',\n  voiceId: 'voice-id',\n  \n  onData: (chunk, isFinal) => {\n    if (chunk.length > 0) {\n      speaker.write(chunk);\n    }\n    \n    if (isFinal) {\n      // End the speaker stream when done\n      setTimeout(() => speaker.end(), 1000);\n    }\n  },\n  \n  onComplete: () => {\n    console.log('Streaming completed');\n    client.close();\n  },\n  \n  onError: (error) => {\n    console.error('Error:', error);\n    speaker.end();\n    client.close();\n  }\n});\n```\n\n### Converting Raw Audio\n\nThe streaming API provides raw PCM audio data. To convert it to a common format like WAV or MP3, you can use FFmpeg or a library like `wav`:\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\nimport * as wav from 'wav';\nimport * as fs from 'fs';\n\n// Install with: npm install wav\n\n// Initialize the client\nconst client = new Client({\n  apiKey: 'your-api-key'\n});\n\n// Create a WAV file writer\nconst fileWriter = new wav.FileWriter('output.wav', {\n  channels: 1,\n  sampleRate: 24000,\n  bitDepth: 16\n});\n\n// Stream speech to WAV file\nconst streamController = client.streamSpeech({\n  text: 'Сайн байна уу! Энэ бол Цэцэн дуу хоолойны шууд урсгал юм.',\n  voiceId: 'voice-id',\n  \n  onData: (chunk, isFinal) => {\n    if (chunk.length > 0) {\n      fileWriter.write(chunk);\n    }\n    \n    if (isFinal) {\n      fileWriter.end();\n    }\n  },\n  \n  onComplete: () => {\n    console.log('WAV file created at output.wav');\n    client.close();\n  },\n  \n  onError: (error) => {\n    console.error('Error:', error);\n    fileWriter.end();\n    client.close();\n  }\n});\n```\n\n### Notes on Streaming\n\n- The streaming audio is provided as raw 16-bit PCM data\n- The sample rate is fixed at 24,000 Hz for the current version\n- Audio is mono (single channel)\n- No additional audio headers are included in the chunks\n- Rate limits apply: free tier is limited to 1 request per minute\n\n## Features\n\n- Generate high-quality Mongolian speech from text\n- List available Mongolian voices\n- Check generation status\n- Get user balance\n- Robust error handling and retries\n- TypeScript support\n\n## API Reference\n\n### Client\n\nThe main entry point to the Tsetsen TTS API.\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\n\nconst client = new Client(options);\n```\n\n#### Constructor Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `apiKey` | `string` | From env var | Your Tsetsen API key |\n| `timeout` | `number` | `30000` | Request timeout in milliseconds |\n| `secure` | `boolean` | `true` | Whether to use TLS for the connection |\n| `maxRetries` | `number` | `3` | Maximum number of retries for failed requests |\n| `logger` | `Logger` | Console | Logger to use |\n\n#### Methods\n\n##### `listVoices(options?): Promise<ListVoicesResponse>`\n\nLists available Mongolian voices for TTS.\n\n```typescript\nconst { voices } = await client.listVoices({ \n  version: 'beta-v0.1', // Required: API version\n  skipCache: false // Optional: Skip cache\n});\n\n// Example voice object\nconsole.log(voices[0]);\n// {\n//   id: 'voice1',\n//   name: 'Voice Name',\n//   gender: Gender.MALE,\n//   language: 'mn'\n// }\n```\n\n##### `generateSpeech(options): Promise<GenerateSpeechResponse>`\n\nGenerates Mongolian speech from text.\n\n```typescript\nconst response = await client.generateSpeech({\n  text: 'Сайн байна уу!', // Mongolian text\n  voiceId: 'voice-id',\n  speed: 1.0, // Optional: Speech speed multiplier (default: 1.0)\n  version: 'beta-v0.1' // Required: API version\n});\n\nconsole.log(response);\n// {\n//   requestId: 'req-123',\n//   status: RequestStatus.PENDING\n// }\n```\n\n##### `checkStatus(requestId): Promise<CheckStatusResponse>`\n\nChecks the status of a speech generation request.\n\n```typescript\nconst status = await client.checkStatus('req-123');\n\nconsole.log(status);\n// {\n//   requestId: 'req-123',\n//   status: RequestStatus.COMPLETED,\n//   audioUrl: 'https://example.com/audio.mp3',\n//   metrics: {\n//     queueTime: 100, // Time in queue (ms)\n//     processingTime: 2000, // Processing time (ms)\n//     totalTime: 2100, // Total time (ms)\n//     audioLength: 3.5, // Audio length (seconds)\n//     creditsUsed: 50, // Credits used\n//     characterCount: 100 // Number of characters processed\n//   }\n// }\n```\n\n##### `getUserBalance(): Promise<GetUserBalanceResponse>`\n\nGets the user's credit balance.\n\n```typescript\nconst balance = await client.getUserBalance();\n\nconsole.log(balance);\n// {\n//   credits: 1000\n// }\n```\n\n##### `waitForCompletion(requestId, options?): Promise<CheckStatusResponse>`\n\nWaits for a speech generation request to complete.\n\n```typescript\nconst result = await client.waitForCompletion('req-123', {\n  timeout: 60000, // Optional: Maximum time to wait (ms)\n  pollInterval: 1000 // Optional: Time between status checks (ms)\n});\n\nconsole.log(result);\n// Same as checkStatus result when complete\n```\n\n##### `close(): void`\n\nCloses the client and releases resources. Call this when you're done with the client.\n\n```typescript\nclient.close();\n```\n\n### Enums\n\n#### `RequestStatus`\n\nStatus of a TTS request.\n\n```typescript\nenum RequestStatus {\n  UNSPECIFIED = 0,\n  PENDING = 1,\n  PROCESSING = 2,\n  COMPLETED = 3,\n  FAILED = 4\n}\n```\n\n#### `Gender`\n\nGender of a voice.\n\n```typescript\nenum Gender {\n  UNSPECIFIED = 0,\n  MALE = 1,\n  FEMALE = 2\n}\n```\n\n### Error Handling\n\nThe SDK provides specialized error classes for different error conditions.\n\n```typescript\nimport { \n  TsetsenError, \n  AuthenticationError,\n  ResourceNotFoundError \n} from '@duran.ai/tsetsen';\n\ntry {\n  await client.generateSpeech({ \n    text: 'Сайн байна уу!',\n    voiceId: 'voice-id',\n    version: 'beta-v0.1'\n  });\n} catch (error) {\n  if (error instanceof AuthenticationError) {\n    console.error('Authentication failed:', error.message);\n  } else if (error instanceof ResourceNotFoundError) {\n    console.error('Resource not found:', error.message);\n  } else if (error instanceof TsetsenError) {\n    console.error('API error:', error.message, error.code);\n    console.error('Details:', error.details);\n  } else {\n    console.error('Unexpected error:', error);\n  }\n}\n```\n\nError classes:\n\n- `TsetsenError`: Base error class\n- `AuthenticationError`: Authentication failed\n- `PermissionDeniedError`: Permission denied\n- `InvalidRequestError`: Invalid request parameters\n- `RateLimitExceededError`: Rate limit exceeded\n- `InsufficientCreditsError`: Insufficient credits\n- `ResourceNotFoundError`: Resource not found\n- `ServiceUnavailableError`: Service unavailable\n- `ConnectionError`: Connection error\n- `TimeoutError`: Request timed out\n- `ServerError`: Server error\n\n## Environment Variables\n\n- `TSETSEN_API_KEY`: API key for authentication (alternative to passing in constructor)\n\n## Testing Your Integration\n\nHere's a simple test to verify your integration is working correctly:\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\n\nasync function testTsetsenIntegration() {\n  const client = new Client({\n    apiKey: process.env.TSETSEN_API_KEY\n  });\n\n  try {\n    // Test Voice Listing\n    const voices = await client.listVoices({ version: 'beta-v0.1' });\n    console.log(`✓ Successfully listed ${voices.voices.length} voices`);\n\n    // Test User Balance\n    const balance = await client.getUserBalance();\n    console.log(`✓ User has ${balance.credits} credits`);\n\n    console.log('All tests passed!');\n  } catch (error) {\n    console.error('Integration test failed:', error);\n  } finally {\n    client.close();\n  }\n}\n\ntestTsetsenIntegration();\n```\n\n---\n\n# Монгол хэл дээрх гарын авлага\n\nЦэцэн Текст-Яриа-Хувиргах (TTS) Node.js SDK нь Монгол хэл дээрх өндөр чанартай яриа үүсгэх энгийн интерфейсийг санал болгодог.\n\n## Суулгах\n\n```bash\nnpm install @duran.ai/tsetsen\n```\n\n## Шаардлага\n\n- Node.js 14.x эсвэл түүнээс дээш хувилбар\n- Цэцэн API түлхүүр ([developer.tsetsen.ai](https://developer.tsetsen.ai) хаягаар бүртгүүлнэ)\n\n## Хурдан эхлэх\n\n```typescript\nimport { Client, RequestStatus } from '@duran.ai/tsetsen';\n\n// Initialize the client with your API key\nconst client = new Client({\n  apiKey: 'your-api-key',\n  // Optional: Specify a timeout for requests\n  timeout: 60000, // 60 seconds\n});\n\nasync function main() {\n  try {\n    // List available Mongolian voices\n    const voicesResponse = await client.listVoices({ version: 'beta-v0.1' });\n    console.log(`Available Mongolian voices: ${voicesResponse.voices.length}`);\n    \n    // Select a voice to use\n    const selectedVoice = voicesResponse.voices[0];\n    console.log(`Using voice: ${selectedVoice.name} (${selectedVoice.id})`);\n    \n    // Generate Mongolian speech\n    const response = await client.generateSpeech({\n      text: 'Сайн байна уу! Би Цэцэн хиймэл оюун ухаан системийн дуу хоолой.',\n      voiceId: selectedVoice.id,\n      version: 'beta-v0.1'\n    });\n    console.log(`Generation request submitted: ${response.requestId}`);\n    \n    // Wait for completion with proper error handling\n    try {\n      const result = await client.waitForCompletion(response.requestId, {\n        timeout: 120000,      // 2 minutes timeout for longer texts\n        pollInterval: 1000    // Check every second\n      });\n      \n      if (result.status === RequestStatus.COMPLETED) {\n        console.log(`Audio URL: ${result.audioUrl}`);\n        \n        // Display metrics if available\n        if (result.metrics) {\n          console.log(`Audio length: ${result.metrics.audioLength} seconds`);\n          console.log(`Processing time: ${result.metrics.processingTime} ms`);\n          console.log(`Credits used: ${result.metrics.creditsUsed}`);\n        }\n      } else {\n        console.log(`Generation failed: ${result.errorMessage}`);\n      }\n    } catch (error) {\n      if (error.code === 'timeout') {\n        console.error('Request timed out. The operation might still complete on the server.');\n      } else {\n        throw error; // rethrow other errors\n      }\n    }\n  } catch (error) {\n    console.error('Error:', error.message);\n    // Handle specific error types\n    if (error.code) {\n      console.error(`Error code: ${error.code}`);\n    }\n  } finally {\n    // Always close the client when done\n    client.close();\n  }\n}\n\nmain();\n```\n\n## Яриа Streaming\n\n`generateSpeech` ашиглан яриаг асинхрон үүсгэхээс гадна SDK нь одоо `streamSpeech` ашиглан бодит цагийн горимд яриаг streaming хийх боломжтой болсон. Энэ нь бүхэл аудио файл үүсэхийг хүлээх шаардлагагүйгээр, аудио хэсгүүдийг үүсгэх үед нь хүлээн авах, боловсруулах боломжийг олгодог.\n\n### Streaming хязгаарлалтууд\n\n- Streaming зөвхөн `beta-v0.2` загвартай ажилладаг\n- Хүсэлтийн хязгаарлалт: Нэг минутанд 1 хүсэлт (үнэгүй эрх)\n- Streaming-ийн хамгийн их үргэлжлэх хугацаа: 5 минут\n- Аудио формат: 24,000Гц, 16-бит, моно\n\n### Энгийн Streaming жишээ\n\n```typescript\nimport { Client, RequestStatus } from '@duran.ai/tsetsen';\nimport * as fs from 'fs';\n\n// Client үүсгэх\nconst client = new Client({\n  apiKey: 'таны-api-түлхүүр' \n});\n\n// Коллбэкүүдтэй яриаг streaming хийх\nconst streamController = client.streamSpeech({\n  text: 'Сайн байна уу! Энэ бол Цэцэн дуу хоолойны шууд урсгал юм.',\n  voiceId: 'дуу-хоолойн-id',\n  version: 'beta-v0.2', // Streaming-д заавал шаардлагатай\n  \n  // Аудио хэсгүүдийг ирэх үед хүлээн авах\n  onData: (audioChunk, isFinal) => {\n    console.log(`Хүлээн авсан хэсэг: ${audioChunk.length} байт, төгсгөл: ${isFinal}`);\n    \n    // Аудио хэсгүүдийг бодит цагийн горимд боловсруулах\n    // Жишээ нь: WebSocket руу илгээх, тоглуулах г.м.\n  },\n  \n  // Streaming дуусахад дуудагдана\n  onComplete: () => {\n    console.log('Streaming амжилттай дууслаа');\n    client.close();\n  },\n  \n  // Алдаа гарвал дуудагдана\n  onError: (error) => {\n    console.error('Streaming алдаа:', error);\n    client.close();\n  }\n});\n\n// Та streaming-ийг дурын үед цуцлах боломжтой\n// streamController.cancel();\n```\n\n### Streaming-ийг файлд хадгалах\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\n\n// Client үүсгэх\nconst client = new Client({\n  apiKey: 'таны-api-түлхүүр'\n});\n\n// Яриаг шууд файлд streaming хийх\nconst streamController = client.streamSpeech({\n  text: 'Сайн байна уу! Энэ бол Цэцэн дуу хоолойны шууд урсгал юм.',\n  voiceId: 'дуу-хоолойн-id',\n  outputFile: 'output.raw', // Файлд хадгалах (түүхий 16-бит PCM формат)\n  \n  onComplete: () => {\n    console.log('Аудио output.raw файлд хадгалагдлаа');\n    client.close();\n  },\n  \n  onError: (error) => {\n    console.error('Алдаа:', error);\n    client.close();\n  }\n});\n```\n\n### Аудиог бодит цагийн горимд тоглуулах\n\nАудиог бодит цагийн горимд тоглуулахын тулд та `speaker` эсвэл `node-aplay` гэх мэт аудио сан ашиглаж болно. `speaker` пакет ашигласан жишээ:\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\nimport Speaker from 'speaker';\n\n// Суулгах: npm install speaker\n\n// Client үүсгэх\nconst client = new Client({\n  apiKey: 'таны-api-түлхүүр'\n});\n\n// Speaker тохируулах\nconst speaker = new Speaker({\n  channels: 1,          // моно\n  bitDepth: 16,         // 16-бит сэмпл\n  sampleRate: 24000,    // 24,000 Гц сэмпл давтамж\n  signed: true          // signed өгөгдөл (PCM16-д зориулсан)\n});\n\n// Яриаг шууд speaker руу streaming хийх\nconst streamController = client.streamSpeech({\n  text: 'Сайн байна уу! Энэ бол Цэцэн дуу хоолойны шууд урсгал юм.',\n  voiceId: 'дуу-хоолойн-id',\n  \n  onData: (chunk, isFinal) => {\n    if (chunk.length > 0) {\n      speaker.write(chunk);\n    }\n    \n    if (isFinal) {\n      // Дууссан үед speaker урсгалыг хаах\n      setTimeout(() => speaker.end(), 1000);\n    }\n  },\n  \n  onComplete: () => {\n    console.log('Streaming дууслаа');\n    client.close();\n  },\n  \n  onError: (error) => {\n    console.error('Алдаа:', error);\n    speaker.end();\n    client.close();\n  }\n});\n```\n\n### Түүхий аудиог хөрвүүлэх\n\nStreaming API нь түүхий PCM аудио өгөгдөл өгдөг. Түүнийг WAV эсвэл MP3 гэх мэт түгээмэл форматад хувиргахын тулд та FFmpeg эсвэл `wav` гэх мэт сан ашиглаж болно:\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\nimport * as wav from 'wav';\nimport * as fs from 'fs';\n\n// Суулгах: npm install wav\n\n// Client үүсгэх\nconst client = new Client({\n  apiKey: 'таны-api-түлхүүр'\n});\n\n// WAV файл үүсгэгч үүсгэх\nconst fileWriter = new wav.FileWriter('output.wav', {\n  channels: 1,\n  sampleRate: 24000,\n  bitDepth: 16\n});\n\n// Яриаг WAV файлд streaming хийх\nconst streamController = client.streamSpeech({\n  text: 'Сайн байна уу! Энэ бол Цэцэн дуу хоолойны шууд урсгал юм.',\n  voiceId: 'дуу-хоолойн-id',\n  \n  onData: (chunk, isFinal) => {\n    if (chunk.length > 0) {\n      fileWriter.write(chunk);\n    }\n    \n    if (isFinal) {\n      fileWriter.end();\n    }\n  },\n  \n  onComplete: () => {\n    console.log('WAV файл output.wav-д үүсгэгдлээ');\n    client.close();\n  },\n  \n  onError: (error) => {\n    console.error('Алдаа:', error);\n    fileWriter.end();\n    client.close();\n  }\n});\n```\n\n### Streaming-ийн тухай тэмдэглэлүүд\n\n- Streaming аудио нь түүхий 16-бит PCM өгөгдөл хэлбэрээр өгөгддөг\n- Сэмпл давтамж нь одоогийн хувилбарт 24,000 Гц-д тогтмол байдаг\n- Аудио нь моно (ганц суваг)\n- Аудио хэсгүүдэд нэмэлт аудио толгой хэсэг (headers) багтаагүй\n- Хүсэлтийн хязгаарлалт үйлчилнэ: үнэгүй эрхийн хувьд нэг минутанд 1 хүсэлтээр хязгаарлагдана\n\n## Боломжууд\n\n- Өндөр чанартай Монгол яриа үүсгэх\n- Боломжтой Монгол дуу хоолойнуудыг жагсаах\n- Үүсгэх хүсэлтийн статусыг шалгах\n- Хэрэглэгчийн балансыг харах\n- Найдвартай алдааны боловсруулалт ба дахин оролдлого\n- TypeScript дэмжлэг\n\n## API Лавлагаа\n\n### Клиент\n\nЦэцэн TTS API-д хандах үндсэн цэг.\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\n\nconst client = new Client(options);\n```\n\n#### Конструкторын Тохиргоо\n\n| Тохиргоо | Төрөл | Үндсэн утга | Тайлбар |\n|----------|-------|-------------|---------|\n| `apiKey` | `string` | Орчны хувьсагчаас | Таны Цэцэн API түлхүүр |\n| `timeout` | `number` | `30000` | Хүсэлтийн хүлээх хугацаа (миллисекунд) |\n| `secure` | `boolean` | `true` | TLS холболт ашиглах эсэх |\n| `maxRetries` | `number` | `3` | Алдаа гарсан үед дахин оролдох хамгийн их тоо |\n| `logger` | `Logger` | Console | Лог бичих механизм |\n\n#### Аргууд\n\n##### `listVoices(options?): Promise<ListVoicesResponse>`\n\nБоломжтой Монгол дуу хоолойнуудыг жагсаана.\n\n```typescript\nconst { voices } = await client.listVoices({ \n  version: 'beta-v0.1', // Шаардлагатай: API хувилбар\n  skipCache: false // Сонголт: Кэшээс алгасах\n});\n\n// Дуу хоолойн обьектын жишээ\nconsole.log(voices[0]);\n// {\n//   id: 'voice1',\n//   name: 'Voice Name',\n//   gender: Gender.MALE,\n//   language: 'mn'\n// }\n```\n\n##### `generateSpeech(options): Promise<GenerateSpeechResponse>`\n\nМонгол текстээс яриа үүсгэнэ.\n\n```typescript\nconst response = await client.generateSpeech({\n  text: 'Сайн байна уу!', // Монгол текст\n  voiceId: 'voice-id',\n  speed: 1.0, // Сонголт: Ярианы хурдны үржүүлэгч (үндсэн: 1.0)\n  version: 'beta-v0.1' // Шаардлагатай: API хувилбар\n});\n\nconsole.log(response);\n// {\n//   requestId: 'req-123',\n//   status: RequestStatus.PENDING\n// }\n```\n\n##### `checkStatus(requestId): Promise<CheckStatusResponse>`\n\nЯриа үүсгэх хүсэлтийн статусыг шалгана.\n\n```typescript\nconst status = await client.checkStatus('req-123');\n\nconsole.log(status);\n// {\n//   requestId: 'req-123',\n//   status: RequestStatus.COMPLETED,\n//   audioUrl: 'https://example.com/audio.mp3',\n//   metrics: {\n//     queueTime: 100, // Дараалалд зарцуулсан хугацаа (мс)\n//     processingTime: 2000, // Боловсруулалтын хугацаа (мс)\n//     totalTime: 2100, // Нийт хугацаа (мс)\n//     audioLength: 3.5, // Аудионы урт (секунд)\n//     creditsUsed: 50, // Ашигласан кредит\n//     characterCount: 100 // Тэмдэгтийн тоо\n//   }\n// }\n```\n\n##### `getUserBalance(): Promise<GetUserBalanceResponse>`\n\nХэрэглэгчийн кредит балансыг авна.\n\n```typescript\nconst balance = await client.getUserBalance();\n\nconsole.log(balance);\n// {\n//   credits: 1000\n// }\n```\n\n##### `waitForCompletion(requestId, options?): Promise<CheckStatusResponse>`\n\nЯриа үүсгэх хүсэлт дуустал хүлээнэ.\n\n```typescript\nconst result = await client.waitForCompletion('req-123', {\n  timeout: 60000, // Сонголт: Хүлээх хамгийн их хугацаа (мс)\n  pollInterval: 1000 // Сонголт: Статус шалгах хоорондын хугацаа (мс)\n});\n\nconsole.log(result);\n// checkStatus үр дүнтэй ижил\n```\n\n##### `close(): void`\n\nКлиентийн холболтыг хаана. Ажил дуусахад заавал дуудна.\n\n```typescript\nclient.close();\n```\n\n### Тоочлолууд (Enums)\n\n#### `RequestStatus`\n\nTTS хүсэлтийн статус.\n\n```typescript\nenum RequestStatus {\n  UNSPECIFIED = 0,\n  PENDING = 1,\n  PROCESSING = 2,\n  COMPLETED = 3,\n  FAILED = 4\n}\n```\n\n#### `Gender`\n\nДуу хоолойн хүйс.\n\n```typescript\nenum Gender {\n  UNSPECIFIED = 0,\n  MALE = 1,\n  FEMALE = 2\n}\n```\n\n### Алдааны боловсруулалт\n\nSDK нь өөр өөр нөхцөлд тохирсон тусгай алдааны ангиудыг санал болгодог.\n\n```typescript\nimport { \n  TsetsenError, \n  AuthenticationError,\n  ResourceNotFoundError \n} from '@duran.ai/tsetsen';\n\ntry {\n  await client.generateSpeech({ \n    text: 'Сайн байна уу!',\n    voiceId: 'voice-id',\n    version: 'beta-v0.1'\n  });\n} catch (error) {\n  if (error instanceof AuthenticationError) {\n    console.error('Нэвтрэлтийн алдаа:', error.message);\n  } else if (error instanceof ResourceNotFoundError) {\n    console.error('Нөөц олдсонгүй:', error.message);\n  } else if (error instanceof TsetsenError) {\n    console.error('API алдаа:', error.message, error.code);\n    console.error('Дэлгэрэнгүй:', error.details);\n  } else {\n    console.error('Тодорхойгүй алдаа:', error);\n  }\n}\n```\n\nАлдааны ангиуд:\n\n- `TsetsenError`: Үндсэн алдааны анги\n- `AuthenticationError`: Нэвтрэлтийн алдаа\n- `PermissionDeniedError`: Зөвшөөрөл хасагдсан\n- `InvalidRequestError`: Буруу хүсэлтийн параметр\n- `RateLimitExceededError`: Хүсэлтийн тоо хэтэрсэн\n- `InsufficientCreditsError`: Кредит хүрэлцээгүй\n- `ResourceNotFoundError`: Нөөц олдсонгүй\n- `ServiceUnavailableError`: Үйлчилгээ түр ажиллахгүй байна\n- `ConnectionError`: Холболтын алдаа\n- `TimeoutError`: Хүсэлт хугацаа хэтэрсэн\n- `ServerError`: Серверийн алдаа\n\n## Орчны хувьсагчид\n\n- `TSETSEN_API_KEY`: Нэвтрэх API түлхүүр (конструктор дээр дамжуулахын оронд)\n\n## Интеграцийг шалгах\n\nИнтеграцийн зөв ажиллагааг шалгах энгийн тест:\n\n```typescript\nimport { Client } from '@duran.ai/tsetsen';\n\nasync function testTsetsenIntegration() {\n  const client = new Client({\n    apiKey: process.env.TSETSEN_API_KEY\n  });\n\n  try {\n    // Дуу хоолой жагсаалтыг шалгах\n    const voices = await client.listVoices({ version: 'beta-v0.1' });\n    console.log(`✓ Амжилттай ${voices.voices.length} дуу хоолой жагсаалаа`);\n\n    // Хэрэглэгчийн балансыг шалгах\n    const balance = await client.getUserBalance();\n    console.log(`✓ Хэрэглэгч ${balance.credits} кредиттэй байна`);\n\n    console.log('Бүх тестүүд амжилттай!');\n  } catch (error) {\n    console.error('Интеграцийн тест амжилтгүй:', error);\n  } finally {\n    client.close();\n  }\n}\n\ntestTsetsenIntegration();\n```","readmeFilename":"README.md"}