mirror of
https://github.com/logos-storage/logos-storage-js.git
synced 2026-01-02 13:33:07 +00:00
Merge 63a868e311548fa9d4baf48365e8e817692c272f into a12da5cca34a7209e30589c9148a9f0cb6d3cbd1
This commit is contained in:
commit
bc8565d4ca
14
README.md
14
README.md
@ -114,6 +114,20 @@ if (slots.error) {
|
||||
// Access the slots within slots.data.
|
||||
```
|
||||
|
||||
If you prefer to use the "classic" JavaScript mode and deal with exceptions, you can import the throwable component instead:
|
||||
|
||||
```js
|
||||
import { Codex } from "@codex-storage/sdk-js/throwable";
|
||||
|
||||
const marketplace = codex.marketplace;
|
||||
|
||||
try {
|
||||
const slots = marketplace.activeSlots();
|
||||
} catch (e) {
|
||||
// Do something
|
||||
}
|
||||
```
|
||||
|
||||
### Compatibility
|
||||
|
||||
| SDK version | Codex version | Codex app |
|
||||
|
||||
17
examples/upload-node-throwable/README.md
Normal file
17
examples/upload-node-throwable/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Download example
|
||||
|
||||
Small example to show how to download a file in the browser with Codex.
|
||||
|
||||
## Install dependencies
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
## Run node
|
||||
|
||||
```bash
|
||||
node index.js
|
||||
```
|
||||
|
||||
Note: You can define `CODEX_NODE_URL`, default value is "http://localhost:8080".
|
||||
18
examples/upload-node-throwable/index.js
Normal file
18
examples/upload-node-throwable/index.js
Normal file
@ -0,0 +1,18 @@
|
||||
const { Codex } = require("@codex-storage/sdk-js/throwable");
|
||||
const { NodeUploadStrategy } = require("@codex-storage/sdk-js/node");
|
||||
|
||||
async function main() {
|
||||
const codex = new Codex(
|
||||
process.env.CODEX_NODE_URL || "http://localhost:8080"
|
||||
);
|
||||
const data = codex.data;
|
||||
|
||||
const strategy = new NodeUploadStrategy("Hello World !");
|
||||
const uploadResponse = data.upload(strategy);
|
||||
|
||||
const cid = await uploadResponse.result;
|
||||
|
||||
console.info("CID is", cid);
|
||||
}
|
||||
|
||||
main();
|
||||
79
examples/upload-node-throwable/package-lock.json
generated
Normal file
79
examples/upload-node-throwable/package-lock.json
generated
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "@codex-storage/sdk-js-update-node-throwable-example",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@codex-storage/sdk-js-update-node-throwable-example",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@codex-storage/sdk-js": "../..",
|
||||
"undici": "^7.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.5.3"
|
||||
}
|
||||
},
|
||||
"..": {
|
||||
"extraneous": true
|
||||
},
|
||||
"../..": {
|
||||
"name": "@codex-storage/sdk-js",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"valibot": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/strictest": "^2.0.5",
|
||||
"@types/node": "^22.13.17",
|
||||
"oas-normalize": "^14.0.0",
|
||||
"openapi-typescript": "^7.6.1",
|
||||
"prettier": "^3.5.3",
|
||||
"tsup": "^8.3.6",
|
||||
"typescript": "^5.8.2",
|
||||
"vitest": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"undici": "^7.7.0"
|
||||
}
|
||||
},
|
||||
"../dist": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@codex-storage/sdk-js": {
|
||||
"resolved": "../..",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
|
||||
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.7.0.tgz",
|
||||
"integrity": "sha512-tZ6+5NBq4KH35rr46XJ2JPFKxfcBlYNaqLF/wyWIO9RMHqqU/gx/CLB1Y2qMcgB8lWw/bKHa7qzspqCN7mUHvA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
examples/upload-node-throwable/package.json
Normal file
16
examples/upload-node-throwable/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "@codex-storage/sdk-js-update-node-throwable-example",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"@codex-storage/sdk-js": "../..",
|
||||
"undici": "^7.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.5.3"
|
||||
}
|
||||
}
|
||||
12
package.json
12
package.json
@ -9,7 +9,7 @@
|
||||
"scripts": {
|
||||
"prepack": "npm run build",
|
||||
"prebuild": "npm run compile && rm -Rf dist/*",
|
||||
"build": "tsup src/index.ts src/async.ts src/browser.ts src/node.ts --format esm,cjs --dts --sourcemap --treeshake",
|
||||
"build": "tsup src/index.ts src/async.ts src/browser.ts src/node.ts src/throwable.ts --format esm,cjs --dts --sourcemap --treeshake",
|
||||
"compile": "tsc --noEmit",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
@ -35,6 +35,16 @@
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"./throwable": {
|
||||
"import": {
|
||||
"types": "./dist/throwable.d.ts",
|
||||
"default": "./dist/throwable.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/throwable.d.cts",
|
||||
"default": "./dist/throwable.js"
|
||||
}
|
||||
},
|
||||
"./browser": {
|
||||
"import": {
|
||||
"types": "./dist/browser.d.ts",
|
||||
|
||||
33
src/data/data.throwable.ts
Normal file
33
src/data/data.throwable.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { CodexData } from "./data";
|
||||
import type { UploadStrategy } from "./types";
|
||||
import { type FetchAuth } from "../fetch-safe/fetch-safe";
|
||||
import { Throwable } from "../throwable/throwable";
|
||||
|
||||
type CodexDataThrowableOptions = {
|
||||
auth?: FetchAuth;
|
||||
};
|
||||
|
||||
export class CodexDataThrowable {
|
||||
readonly data: CodexData;
|
||||
|
||||
constructor(url: string, options?: CodexDataThrowableOptions) {
|
||||
this.data = new CodexData(url, options);
|
||||
}
|
||||
|
||||
cids = () => Throwable.from(this.data.cids());
|
||||
space = () => Throwable.from(this.data.space());
|
||||
upload = (strategy: UploadStrategy) => {
|
||||
const { result, abort } = this.data.upload(strategy);
|
||||
return {
|
||||
result: Throwable.from(result),
|
||||
abort,
|
||||
};
|
||||
};
|
||||
localDownload = (cid: string) => Throwable.from(this.data.localDownload(cid));
|
||||
networkDownload = (cid: string) =>
|
||||
Throwable.from(this.data.networkDownload(cid));
|
||||
networkDownloadStream = (cid: string) =>
|
||||
Throwable.from(this.data.networkDownloadStream(cid));
|
||||
fetchManifest = (cid: string) => Throwable.from(this.data.fetchManifest(cid));
|
||||
delete = (cid: string) => Throwable.from(this.data.delete(cid));
|
||||
}
|
||||
20
src/debug/debug.throwable.ts
Normal file
20
src/debug/debug.throwable.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import type { CodexLogLevel } from "./types";
|
||||
import { type FetchAuth } from "../fetch-safe/fetch-safe";
|
||||
import { Throwable } from "../throwable/throwable";
|
||||
import { CodexDebug } from "./debug";
|
||||
|
||||
type CodexDebugThrowableOptions = {
|
||||
auth?: FetchAuth;
|
||||
};
|
||||
|
||||
export class CodexDebugThrowable {
|
||||
readonly debug: CodexDebug;
|
||||
|
||||
constructor(url: string, options?: CodexDebugThrowableOptions) {
|
||||
this.debug = new CodexDebug(url, options);
|
||||
}
|
||||
|
||||
setLogLevel = (level: CodexLogLevel) =>
|
||||
Throwable.from(this.debug.setLogLevel(level));
|
||||
info = () => Throwable.from(this.debug.info());
|
||||
}
|
||||
37
src/marketplace/marketplace.throwable.ts
Normal file
37
src/marketplace/marketplace.throwable.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { type FetchAuth } from "../fetch-safe/fetch-safe";
|
||||
import { Throwable } from "../throwable/throwable";
|
||||
import { CodexMarketplace } from "./marketplace";
|
||||
import type {
|
||||
CodexAvailabilityPatchInput,
|
||||
CodexCreateAvailabilityInput,
|
||||
CodexCreateStorageRequestInput,
|
||||
} from "./types";
|
||||
|
||||
type CodexMarketplaceThrowableOptions = {
|
||||
auth?: FetchAuth;
|
||||
};
|
||||
|
||||
export class CodexMarketplaceThrowable {
|
||||
readonly marketplace: CodexMarketplace;
|
||||
|
||||
constructor(url: string, options?: CodexMarketplaceThrowableOptions) {
|
||||
this.marketplace = new CodexMarketplace(url, options);
|
||||
}
|
||||
|
||||
activeSlots = () => Throwable.from(this.marketplace.activeSlots());
|
||||
activeSlot = (slotId: string) =>
|
||||
Throwable.from(this.marketplace.activeSlot(slotId));
|
||||
availabilities = () => Throwable.from(this.marketplace.availabilities());
|
||||
createAvailability = (input: CodexCreateAvailabilityInput) =>
|
||||
Throwable.from(this.marketplace.createAvailability(input));
|
||||
updateAvailability = (input: CodexAvailabilityPatchInput) =>
|
||||
Throwable.from(this.marketplace.updateAvailability(input));
|
||||
reservations = (availabilityId: string) =>
|
||||
Throwable.from(this.marketplace.reservations(availabilityId));
|
||||
purchaseIds = () => Throwable.from(this.marketplace.purchaseIds());
|
||||
purchases = () => Throwable.from(this.marketplace.purchases());
|
||||
purchaseDetail = (purchaseId: string) =>
|
||||
Throwable.from(this.marketplace.purchaseDetail(purchaseId));
|
||||
createStorageRequest = (input: CodexCreateStorageRequestInput) =>
|
||||
Throwable.from(this.marketplace.createStorageRequest(input));
|
||||
}
|
||||
23
src/node/node.throwable.ts
Normal file
23
src/node/node.throwable.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import type { CodexPeerIdContentType, CodexSprContentType } from "./types";
|
||||
import { type FetchAuth } from "../fetch-safe/fetch-safe";
|
||||
import { Throwable } from "../throwable/throwable";
|
||||
import { CodexNode } from "./node";
|
||||
|
||||
type CodexNodeThrowableOptions = {
|
||||
auth?: FetchAuth;
|
||||
};
|
||||
|
||||
export class CodexNodeThrowable {
|
||||
readonly node: CodexNode;
|
||||
|
||||
constructor(url: string, options?: CodexNodeThrowableOptions) {
|
||||
this.node = new CodexNode(url, options);
|
||||
}
|
||||
|
||||
connect = (peerId: string, addrs: string[] = []) =>
|
||||
Throwable.from(this.node.connect(peerId, addrs));
|
||||
spr = (type: CodexSprContentType = "json") =>
|
||||
Throwable.from(this.node.spr(type));
|
||||
peerId = (type: CodexPeerIdContentType = "json") =>
|
||||
Throwable.from(this.node.peerId(type));
|
||||
}
|
||||
84
src/throwable.ts
Normal file
84
src/throwable.ts
Normal file
@ -0,0 +1,84 @@
|
||||
import { CodexDataThrowable } from "./data/data.throwable";
|
||||
import { CodexNodeThrowable } from "./node/node.throwable";
|
||||
import { CodexMarketplaceThrowable } from "./marketplace/marketplace.throwable";
|
||||
import { CodexDebugThrowable } from "./debug/debug.throwable";
|
||||
import type { FetchAuth } from "./fetch-safe/fetch-safe";
|
||||
|
||||
export * from "./fetch-safe/fetch-safe";
|
||||
export * from "./marketplace/types";
|
||||
export * from "./debug/types";
|
||||
export * from "./data/types";
|
||||
export * from "./values/values";
|
||||
export * from "./errors/errors";
|
||||
|
||||
export { CodexDebugThrowable } from "./debug/debug.throwable";
|
||||
export { CodexDataThrowable } from "./data/data.throwable";
|
||||
export { CodexNodeThrowable } from "./node/node.throwable";
|
||||
export { CodexMarketplaceThrowable } from "./marketplace/marketplace.throwable";
|
||||
|
||||
type CodexProps = {
|
||||
auth?: FetchAuth;
|
||||
};
|
||||
|
||||
export class Codex {
|
||||
readonly url: string;
|
||||
private _marketplace: CodexMarketplaceThrowable | null;
|
||||
private _data: CodexDataThrowable | null;
|
||||
private _node: CodexNodeThrowable | null;
|
||||
private _debug: CodexDebugThrowable | null;
|
||||
private readonly auth: FetchAuth = {};
|
||||
|
||||
constructor(url: string, options?: CodexProps) {
|
||||
this.url = url;
|
||||
this._marketplace = null;
|
||||
this._data = null;
|
||||
this._node = null;
|
||||
this._debug = null;
|
||||
|
||||
if (options?.auth) {
|
||||
this.auth = options?.auth;
|
||||
}
|
||||
}
|
||||
|
||||
get marketplace() {
|
||||
if (this._marketplace) {
|
||||
return this._marketplace;
|
||||
}
|
||||
|
||||
this._marketplace = new CodexMarketplaceThrowable(this.url, {
|
||||
auth: this.auth,
|
||||
});
|
||||
|
||||
return this._marketplace;
|
||||
}
|
||||
|
||||
get data() {
|
||||
if (this._data) {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
this._data = new CodexDataThrowable(this.url, { auth: this.auth });
|
||||
|
||||
return this._data;
|
||||
}
|
||||
|
||||
get node() {
|
||||
if (this._node) {
|
||||
return this._node;
|
||||
}
|
||||
|
||||
this._node = new CodexNodeThrowable(this.url, { auth: this.auth });
|
||||
|
||||
return this._node;
|
||||
}
|
||||
|
||||
get debug() {
|
||||
if (this._debug) {
|
||||
return this._debug;
|
||||
}
|
||||
|
||||
this._debug = new CodexDebugThrowable(this.url, { auth: this.auth });
|
||||
|
||||
return this._debug;
|
||||
}
|
||||
}
|
||||
19
src/throwable/throwable.spec.ts
Normal file
19
src/throwable/throwable.spec.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { assert, describe, it } from "vitest";
|
||||
import { CodexDataThrowable } from "../data/data.throwable";
|
||||
import { CodexError } from "../errors/errors";
|
||||
|
||||
describe("data", () => {
|
||||
const data = new CodexDataThrowable(
|
||||
process.env["CLIENT_URL"] || "http://localhost:8080"
|
||||
);
|
||||
|
||||
it("returns an error when providing an invalid cid", async () => {
|
||||
try {
|
||||
await data.delete("hello");
|
||||
assert.fail();
|
||||
} catch (e) {
|
||||
assert.ok(e instanceof CodexError);
|
||||
assert.ok(e.message.includes("Incorrect Cid"));
|
||||
}
|
||||
});
|
||||
});
|
||||
13
src/throwable/throwable.ts
Normal file
13
src/throwable/throwable.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { SafeValue } from "../values/values";
|
||||
|
||||
export const Throwable = {
|
||||
async from<T>(safePromise: Promise<SafeValue<T>>): Promise<T> {
|
||||
const result = await safePromise;
|
||||
|
||||
if (result.error) {
|
||||
throw result.data;
|
||||
}
|
||||
|
||||
return result.data;
|
||||
},
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user