Skip to content

feat: add throwable usage #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const slots = marketplace.activeSlots();
const slots = await marketplace.activeSlots();

Shouldn't it be like this?

} catch (e) {
// Do something
}
```

### Compatibility

| SDK version | Codex version | Codex app |
Expand Down
17 changes: 17 additions & 0 deletions examples/upload-node-throwable/README.md
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions examples/upload-node-throwable/index.js
Original file line number Diff line number Diff line change
@@ -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 changes: 79 additions & 0 deletions examples/upload-node-throwable/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions examples/upload-node-throwable/package.json
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
33 changes: 33 additions & 0 deletions src/data/data.throwable.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions src/debug/debug.throwable.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 37 additions & 0 deletions src/marketplace/marketplace.throwable.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions src/node/node.throwable.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 84 additions & 0 deletions src/throwable.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}
Loading