@helia/json 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -0
- package/README.md +59 -0
- package/dist/index.min.js +3 -0
- package/dist/src/index.d.ts +88 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +51 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +156 -0
- package/src/index.ts +120 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/ipfs/helia" title="Helia">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/ipfs/helia/main/assets/helia.png" alt="Helia logo" width="300" />
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
# @helia/json <!-- omit in toc -->
|
|
8
|
+
|
|
9
|
+
[](https://ipfs.tech)
|
|
10
|
+
[](https://discuss.ipfs.tech)
|
|
11
|
+
[](https://codecov.io/gh/ipfs/helia-json)
|
|
12
|
+
[](https://github.com/ipfs/helia-json/actions/workflows/js-test-and-release.yml?query=branch%3Amain)
|
|
13
|
+
|
|
14
|
+
> Add/get IPLD blocks containing strings with your Helia node
|
|
15
|
+
|
|
16
|
+
## Table of contents <!-- omit in toc -->
|
|
17
|
+
|
|
18
|
+
- [Install](#install)
|
|
19
|
+
- [Browser `<script>` tag](#browser-script-tag)
|
|
20
|
+
- [API Docs](#api-docs)
|
|
21
|
+
- [License](#license)
|
|
22
|
+
- [Contribute](#contribute)
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```console
|
|
27
|
+
$ npm i @helia/json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Browser `<script>` tag
|
|
31
|
+
|
|
32
|
+
Loading this module through a script tag will make it's exports available as `HeliaStrings` in the global namespace.
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<script src="https://unpkg.com/@helia/json/dist/index.min.js"></script>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API Docs
|
|
39
|
+
|
|
40
|
+
- <https://ipfs.github.io/helia-json/modules/_helia_strings.html>
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
Licensed under either of
|
|
45
|
+
|
|
46
|
+
- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
|
|
47
|
+
- MIT ([LICENSE-MIT](LICENSE-MIT) / <http://opensource.org/licenses/MIT>)
|
|
48
|
+
|
|
49
|
+
## Contribute
|
|
50
|
+
|
|
51
|
+
Contributions welcome! Please check out [the issues](https://github.com/ipfs/helia-json/issues).
|
|
52
|
+
|
|
53
|
+
Also see our [contributing document](https://github.com/ipfs/community/blob/master/CONTRIBUTING_JS.md) for more information on how we work, and about contributing in general.
|
|
54
|
+
|
|
55
|
+
Please be aware that all interactions related to this repo are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
|
|
56
|
+
|
|
57
|
+
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
|
58
|
+
|
|
59
|
+
[](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
(function (root, factory) {(typeof module === 'object' && module.exports) ? module.exports = factory() : root.HeliaJson = factory()}(typeof self !== 'undefined' ? self : this, function () {
|
|
2
|
+
"use strict";var HeliaJson=(()=>{var k=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var we=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var ge=(r,e)=>{for(var t in e)k(r,t,{get:e[t],enumerable:!0})},xe=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of we(e))!be.call(r,o)&&o!==t&&k(r,o,{get:()=>e[o],enumerable:!(n=le(e,o))||n.enumerable});return r};var me=r=>xe(k({},"__esModule",{value:!0}),r);var Ye={};ge(Ye,{json:()=>Ze});var ye=W,K=128,ve=127,Ae=~ve,Se=Math.pow(2,31);function W(r,e,t){e=e||[],t=t||0;for(var n=t;r>=Se;)e[t++]=r&255|K,r/=128;for(;r&Ae;)e[t++]=r&255|K,r>>>=7;return e[t]=r|0,W.bytes=t-n+1,e}var Ee=I,Ue=128,H=127;function I(r,n){var t=0,n=n||0,o=0,s=n,i,a=r.length;do{if(s>=a)throw I.bytes=0,new RangeError("Could not decode varint");i=r[s++],t+=o<28?(i&H)<<o:(i&H)*Math.pow(2,o),o+=7}while(i>=Ue);return I.bytes=s-n,t}var ze=Math.pow(2,7),Ce=Math.pow(2,14),Me=Math.pow(2,21),Ne=Math.pow(2,28),Oe=Math.pow(2,35),Te=Math.pow(2,42),Ve=Math.pow(2,49),De=Math.pow(2,56),Le=Math.pow(2,63),Be=function(r){return r<ze?1:r<Ce?2:r<Me?3:r<Ne?4:r<Oe?5:r<Te?6:r<Ve?7:r<De?8:r<Le?9:10},$e={encode:ye,decode:Ee,encodingLength:Be},ke=$e,O=ke;var T=(r,e=0)=>[O.decode(r,e),O.decode.bytes],z=(r,e,t=0)=>(O.encode(r,e,t),e),C=r=>O.encodingLength(r);var rt=new Uint8Array(0);var Y=(r,e)=>{if(r===e)return!0;if(r.byteLength!==e.byteLength)return!1;for(let t=0;t<r.byteLength;t++)if(r[t]!==e[t])return!1;return!0},M=r=>{if(r instanceof Uint8Array&&r.constructor.name==="Uint8Array")return r;if(r instanceof ArrayBuffer)return new Uint8Array(r);if(ArrayBuffer.isView(r))return new Uint8Array(r.buffer,r.byteOffset,r.byteLength);throw new Error("Unknown type, must be binary type")};var V=(r,e)=>{let t=e.byteLength,n=C(r),o=n+C(t),s=new Uint8Array(o+t);return z(r,s,0),z(t,s,n),s.set(e,o),new N(r,t,e,s)},_=r=>{let e=M(r),[t,n]=T(e),[o,s]=T(e.subarray(n)),i=e.subarray(n+s);if(i.byteLength!==o)throw new Error("Incorrect length");return new N(t,o,i,e)},ee=(r,e)=>{if(r===e)return!0;{let t=e;return r.code===t.code&&r.size===t.size&&t.bytes instanceof Uint8Array&&Y(r.bytes,t.bytes)}},N=class{constructor(e,t,n,o){this.code=e,this.size=t,this.digest=n,this.bytes=o}};function Ie(r,e){if(r.length>=255)throw new TypeError("Alphabet too long");for(var t=new Uint8Array(256),n=0;n<t.length;n++)t[n]=255;for(var o=0;o<r.length;o++){var s=r.charAt(o),i=s.charCodeAt(0);if(t[i]!==255)throw new TypeError(s+" is ambiguous");t[i]=o}var a=r.length,h=r.charAt(0),E=Math.log(a)/Math.log(256),p=Math.log(256)/Math.log(a);function U(c){if(c instanceof Uint8Array||(ArrayBuffer.isView(c)?c=new Uint8Array(c.buffer,c.byteOffset,c.byteLength):Array.isArray(c)&&(c=Uint8Array.from(c))),!(c instanceof Uint8Array))throw new TypeError("Expected Uint8Array");if(c.length===0)return"";for(var f=0,S=0,l=0,b=c.length;l!==b&&c[l]===0;)l++,f++;for(var g=(b-l)*p+1>>>0,u=new Uint8Array(g);l!==b;){for(var x=c[l],A=0,w=g-1;(x!==0||A<S)&&w!==-1;w--,A++)x+=256*u[w]>>>0,u[w]=x%a>>>0,x=x/a>>>0;if(x!==0)throw new Error("Non-zero carry");S=A,l++}for(var y=g-S;y!==g&&u[y]===0;)y++;for(var $=h.repeat(f);y<g;++y)$+=r.charAt(u[y]);return $}function B(c){if(typeof c!="string")throw new TypeError("Expected String");if(c.length===0)return new Uint8Array;var f=0;if(c[f]!==" "){for(var S=0,l=0;c[f]===h;)S++,f++;for(var b=(c.length-f)*E+1>>>0,g=new Uint8Array(b);c[f];){var u=t[c.charCodeAt(f)];if(u===255)return;for(var x=0,A=b-1;(u!==0||x<l)&&A!==-1;A--,x++)u+=a*g[A]>>>0,g[A]=u%256>>>0,u=u/256>>>0;if(u!==0)throw new Error("Non-zero carry");l=x,f++}if(c[f]!==" "){for(var w=b-l;w!==b&&g[w]===0;)w++;for(var y=new Uint8Array(S+(b-w)),$=S;w!==b;)y[$++]=g[w++];return y}}}function ue(c){var f=B(c);if(f)return f;throw new Error(`Non-${e} character`)}return{encode:U,decodeUnsafe:B,decode:ue}}var Fe=Ie,je=Fe,re=je;var F=class{constructor(e,t,n){this.name=e,this.prefix=t,this.baseEncode=n}encode(e){if(e instanceof Uint8Array)return`${this.prefix}${this.baseEncode(e)}`;throw Error("Unknown type, must be binary type")}},j=class{constructor(e,t,n){if(this.name=e,this.prefix=t,t.codePointAt(0)===void 0)throw new Error("Invalid prefix character");this.prefixCodePoint=t.codePointAt(0),this.baseDecode=n}decode(e){if(typeof e=="string"){if(e.codePointAt(0)!==this.prefixCodePoint)throw Error(`Unable to decode multibase string ${JSON.stringify(e)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);return this.baseDecode(e.slice(this.prefix.length))}else throw Error("Can only multibase decode strings")}or(e){return ne(this,e)}},q=class{constructor(e){this.decoders=e}or(e){return ne(this,e)}decode(e){let t=e[0],n=this.decoders[t];if(n)return n.decode(e);throw RangeError(`Unable to decode multibase string ${JSON.stringify(e)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`)}},ne=(r,e)=>new q({...r.decoders||{[r.prefix]:r},...e.decoders||{[e.prefix]:e}}),R=class{constructor(e,t,n,o){this.name=e,this.prefix=t,this.baseEncode=n,this.baseDecode=o,this.encoder=new F(e,t,n),this.decoder=new j(e,t,o)}encode(e){return this.encoder.encode(e)}decode(e){return this.decoder.decode(e)}},oe=({name:r,prefix:e,encode:t,decode:n})=>new R(r,e,t,n),J=({prefix:r,name:e,alphabet:t})=>{let{encode:n,decode:o}=re(t,e);return oe({prefix:r,name:e,encode:n,decode:s=>M(o(s))})},qe=(r,e,t,n)=>{let o={};for(let p=0;p<e.length;++p)o[e[p]]=p;let s=r.length;for(;r[s-1]==="=";)--s;let i=new Uint8Array(s*t/8|0),a=0,h=0,E=0;for(let p=0;p<s;++p){let U=o[r[p]];if(U===void 0)throw new SyntaxError(`Non-${n} character`);h=h<<t|U,a+=t,a>=8&&(a-=8,i[E++]=255&h>>a)}if(a>=t||255&h<<8-a)throw new SyntaxError("Unexpected end of data");return i},Re=(r,e,t)=>{let n=e[e.length-1]==="=",o=(1<<t)-1,s="",i=0,a=0;for(let h=0;h<r.length;++h)for(a=a<<8|r[h],i+=8;i>t;)i-=t,s+=e[o&a>>i];if(i&&(s+=e[o&a<<t-i]),n)for(;s.length*t&7;)s+="=";return s},m=({name:r,prefix:e,bitsPerChar:t,alphabet:n})=>oe({prefix:e,name:r,encode(o){return Re(o,n,t)},decode(o){return qe(o,n,t,r)}});var v=J({name:"base58btc",prefix:"z",alphabet:"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"}),ht=J({name:"base58flickr",prefix:"Z",alphabet:"123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"});var D=m({prefix:"b",name:"base32",alphabet:"abcdefghijklmnopqrstuvwxyz234567",bitsPerChar:5}),ut=m({prefix:"B",name:"base32upper",alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",bitsPerChar:5}),lt=m({prefix:"c",name:"base32pad",alphabet:"abcdefghijklmnopqrstuvwxyz234567=",bitsPerChar:5}),wt=m({prefix:"C",name:"base32padupper",alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",bitsPerChar:5}),bt=m({prefix:"v",name:"base32hex",alphabet:"0123456789abcdefghijklmnopqrstuv",bitsPerChar:5}),gt=m({prefix:"V",name:"base32hexupper",alphabet:"0123456789ABCDEFGHIJKLMNOPQRSTUV",bitsPerChar:5}),xt=m({prefix:"t",name:"base32hexpad",alphabet:"0123456789abcdefghijklmnopqrstuv=",bitsPerChar:5}),mt=m({prefix:"T",name:"base32hexpadupper",alphabet:"0123456789ABCDEFGHIJKLMNOPQRSTUV=",bitsPerChar:5}),yt=m({prefix:"h",name:"base32z",alphabet:"ybndrfg8ejkmcpqxot1uwisza345h769",bitsPerChar:5});var se=(r,e)=>{let{bytes:t,version:n}=r;switch(n){case 0:return Pe(t,P(r),e||v.encoder);default:return Qe(t,P(r),e||D.encoder)}};var ie=new WeakMap,P=r=>{let e=ie.get(r);if(e==null){let t=new Map;return ie.set(r,t),t}return e},d=class{constructor(e,t,n,o){this.code=t,this.version=e,this.multihash=n,this.bytes=o,this["/"]=o}get asCID(){return this}get byteOffset(){return this.bytes.byteOffset}get byteLength(){return this.bytes.byteLength}toV0(){switch(this.version){case 0:return this;case 1:{let{code:e,multihash:t}=this;if(e!==L)throw new Error("Cannot convert a non dag-pb CID to CIDv0");if(t.code!==Ge)throw new Error("Cannot convert non sha2-256 multihash CID to CIDv0");return d.createV0(t)}default:throw Error(`Can not convert CID version ${this.version} to version 0. This is a bug please report`)}}toV1(){switch(this.version){case 0:{let{code:e,digest:t}=this.multihash,n=V(e,t);return d.createV1(this.code,n)}case 1:return this;default:throw Error(`Can not convert CID version ${this.version} to version 1. This is a bug please report`)}}equals(e){return d.equals(this,e)}static equals(e,t){let n=t;return n&&e.code===n.code&&e.version===n.version&&ee(e.multihash,n.multihash)}toString(e){return se(this,e)}toJSON(){return{"/":se(this)}}link(){return this}get[Symbol.toStringTag](){return"CID"}[Symbol.for("nodejs.util.inspect.custom")](){return`CID(${this.toString()})`}static asCID(e){if(e==null)return null;let t=e;if(t instanceof d)return t;if(t["/"]!=null&&t["/"]===t.bytes||t.asCID===t){let{version:n,code:o,multihash:s,bytes:i}=t;return new d(n,o,s,i||ce(n,o,s.bytes))}else if(t[Xe]===!0){let{version:n,multihash:o,code:s}=t,i=_(o);return d.create(n,s,i)}else return null}static create(e,t,n){if(typeof t!="number")throw new Error("String codecs are no longer supported");if(!(n.bytes instanceof Uint8Array))throw new Error("Invalid digest");switch(e){case 0:{if(t!==L)throw new Error(`Version 0 CID must use dag-pb (code: ${L}) block encoding`);return new d(e,t,n,n.bytes)}case 1:{let o=ce(e,t,n.bytes);return new d(e,t,n,o)}default:throw new Error("Invalid version")}}static createV0(e){return d.create(0,L,e)}static createV1(e,t){return d.create(1,e,t)}static decode(e){let[t,n]=d.decodeFirst(e);if(n.length)throw new Error("Incorrect length");return t}static decodeFirst(e){let t=d.inspectBytes(e),n=t.size-t.multihashSize,o=M(e.subarray(n,n+t.multihashSize));if(o.byteLength!==t.multihashSize)throw new Error("Incorrect length");let s=o.subarray(t.multihashSize-t.digestSize),i=new N(t.multihashCode,t.digestSize,s,o);return[t.version===0?d.createV0(i):d.createV1(t.codec,i),e.subarray(t.size)]}static inspectBytes(e){let t=0,n=()=>{let[U,B]=T(e.subarray(t));return t+=B,U},o=n(),s=L;if(o===18?(o=0,t=0):s=n(),o!==0&&o!==1)throw new RangeError(`Invalid CID version ${o}`);let i=t,a=n(),h=n(),E=t+h,p=E-i;return{version:o,codec:s,multihashCode:a,digestSize:h,multihashSize:p,size:E}}static parse(e,t){let[n,o]=Je(e,t),s=d.decode(o);if(s.version===0&&e[0]!=="Q")throw Error("Version 0 CID string must not include multibase prefix");return P(s).set(n,e),s}},Je=(r,e)=>{switch(r[0]){case"Q":{let t=e||v;return[v.prefix,t.decode(`${v.prefix}${r}`)]}case v.prefix:{let t=e||v;return[v.prefix,t.decode(r)]}case D.prefix:{let t=e||D;return[D.prefix,t.decode(r)]}default:{if(e==null)throw Error("To parse non base32 or base58btc encoded CID multibase decoder must be provided");return[r[0],e.decode(r)]}}},Pe=(r,e,t)=>{let{prefix:n}=t;if(n!==v.prefix)throw Error(`Cannot string encode V0 in ${t.name} encoding`);let o=e.get(n);if(o==null){let s=t.encode(r).slice(1);return e.set(n,s),s}else return o},Qe=(r,e,t)=>{let{prefix:n}=t,o=e.get(n);if(o==null){let s=t.encode(r);return e.set(n,s),s}else return o},L=112,Ge=18,ce=(r,e,t)=>{let n=C(r),o=n+C(e),s=new Uint8Array(o+t.byteLength);return z(r,s,0),z(e,s,n),s.set(t,o),s},Xe=Symbol.for("@ipld/js-cid/CID");var Ke=new TextEncoder,He=new TextDecoder;var ae=512,de=r=>Ke.encode(JSON.stringify(r)),he=r=>JSON.parse(He.decode(r));var G=({name:r,code:e,encode:t})=>new Q(r,e,t),Q=class{constructor(e,t,n){this.name=e,this.code=t,this.encode=n}digest(e){if(e instanceof Uint8Array){let t=this.encode(e);return t instanceof Uint8Array?V(this.code,t):t.then(n=>V(this.code,n))}else throw Error("Unknown type, must be binary type")}};var fe=r=>async e=>new Uint8Array(await crypto.subtle.digest(r,e)),pe=G({name:"sha2-256",code:18,encode:fe("SHA-256")}),Nt=G({name:"sha2-512",code:19,encode:fe("SHA-512")});var X=class{components;constructor(e){this.components=e}async add(e,t={}){let n=de(e),o=await(t.hasher??pe).digest(n),s=d.createV1(ae,o);return await this.components.blockstore.put(s,n,t),s}async get(e,t={}){let n=await this.components.blockstore.get(e,t);return he(n)}};function Ze(r){return new X(r)}return me(Ye);})();
|
|
3
|
+
return HeliaJson}));
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* `@helia/json` makes working with strings {@link https://github.com/ipfs/helia Helia} simple & straightforward.
|
|
5
|
+
*
|
|
6
|
+
* See the {@link Strings Strings interface} for all available operations.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createHelia } from 'helia'
|
|
12
|
+
* import { json } from '@helia/json'
|
|
13
|
+
* import { CID } from 'multiformats/cid'
|
|
14
|
+
*
|
|
15
|
+
* const j = json(helia)
|
|
16
|
+
* const cid = await j.put({
|
|
17
|
+
* hello: 'world'
|
|
18
|
+
* })
|
|
19
|
+
* const obj = await j.get(cid)
|
|
20
|
+
*
|
|
21
|
+
* console.info(obj)
|
|
22
|
+
* // { hello: 'world' }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import { CID } from 'multiformats/cid';
|
|
26
|
+
import type { Blocks, GetBlockProgressEvents, PutBlockProgressEvents } from '@helia/interface/blocks';
|
|
27
|
+
import type { AbortOptions } from '@libp2p/interfaces';
|
|
28
|
+
import type { BlockCodec } from 'multiformats/codecs/interface';
|
|
29
|
+
import type { MultihashHasher } from 'multiformats/hashes/interface';
|
|
30
|
+
import type { ProgressOptions } from 'progress-events';
|
|
31
|
+
export interface JSONComponents {
|
|
32
|
+
blockstore: Blocks;
|
|
33
|
+
}
|
|
34
|
+
export interface AddOptions extends AbortOptions, ProgressOptions<PutBlockProgressEvents> {
|
|
35
|
+
hasher: MultihashHasher;
|
|
36
|
+
}
|
|
37
|
+
export interface GetOptions extends AbortOptions, ProgressOptions<GetBlockProgressEvents> {
|
|
38
|
+
codec: BlockCodec<any, unknown>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The JSON interface provides a simple and intuitive way to add/get objects
|
|
42
|
+
* with your Helia node and is a great place to start learning about IPFS.
|
|
43
|
+
*/
|
|
44
|
+
export interface JSON {
|
|
45
|
+
/**
|
|
46
|
+
* Add an object to your Helia node and get a CID that refers to the block the
|
|
47
|
+
* object has been stored as.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
*
|
|
51
|
+
* ```typescript
|
|
52
|
+
* import { json } from '@helia/json'
|
|
53
|
+
*
|
|
54
|
+
* const j = json(helia)
|
|
55
|
+
* const cid = await str.add({ hello: 'world' })
|
|
56
|
+
*
|
|
57
|
+
* console.info(cid)
|
|
58
|
+
* // CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea)
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
add: (str: unknown, options?: Partial<AddOptions>) => Promise<CID>;
|
|
62
|
+
/**
|
|
63
|
+
* Get an object from your Helia node, either previously added to it or to
|
|
64
|
+
* another node on the network.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
*
|
|
68
|
+
* ```typescript
|
|
69
|
+
* import { json } from '@helia/json'
|
|
70
|
+
* import { CID } from 'multiformats/cid'
|
|
71
|
+
*
|
|
72
|
+
* const j = json(helia)
|
|
73
|
+
* const cid = CID.parse('bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea')
|
|
74
|
+
* const obj = await j.get(cid)
|
|
75
|
+
*
|
|
76
|
+
* console.info(obj)
|
|
77
|
+
* // { hello: 'world' }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
get: <T>(cid: CID, options?: Partial<GetOptions>) => Promise<T>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create a {@link JSON} instance for use with {@link https://github.com/ipfs/helia Helia}
|
|
84
|
+
*/
|
|
85
|
+
export declare function json(helia: {
|
|
86
|
+
blockstore: Blocks;
|
|
87
|
+
}): JSON;
|
|
88
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAGtC,OAAO,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AACrG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,UAAW,SAAQ,YAAY,EAAE,eAAe,CAAC,sBAAsB,CAAC;IACvF,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,MAAM,WAAW,UAAW,SAAQ,YAAY,EAAE,eAAe,CAAC,sBAAsB,CAAC;IACvF,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,IAAI;IACnB;;;;;;;;;;;;;;;OAeG;IACH,GAAG,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IAElE;;;;;;;;;;;;;;;;;OAiBG;IACH,GAAG,EAAE,CAAC,CAAC,EAAG,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CACjE;AA0BD;;GAEG;AACH,wBAAgB,IAAI,CAAE,KAAK,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAEzD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* `@helia/json` makes working with strings {@link https://github.com/ipfs/helia Helia} simple & straightforward.
|
|
5
|
+
*
|
|
6
|
+
* See the {@link Strings Strings interface} for all available operations.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createHelia } from 'helia'
|
|
12
|
+
* import { json } from '@helia/json'
|
|
13
|
+
* import { CID } from 'multiformats/cid'
|
|
14
|
+
*
|
|
15
|
+
* const j = json(helia)
|
|
16
|
+
* const cid = await j.put({
|
|
17
|
+
* hello: 'world'
|
|
18
|
+
* })
|
|
19
|
+
* const obj = await j.get(cid)
|
|
20
|
+
*
|
|
21
|
+
* console.info(obj)
|
|
22
|
+
* // { hello: 'world' }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import { CID } from 'multiformats/cid';
|
|
26
|
+
import * as jsonCodec from 'multiformats/codecs/json';
|
|
27
|
+
import { sha256 } from 'multiformats/hashes/sha2';
|
|
28
|
+
class DefaultJSON {
|
|
29
|
+
components;
|
|
30
|
+
constructor(components) {
|
|
31
|
+
this.components = components;
|
|
32
|
+
}
|
|
33
|
+
async add(obj, options = {}) {
|
|
34
|
+
const buf = jsonCodec.encode(obj);
|
|
35
|
+
const hash = await (options.hasher ?? sha256).digest(buf);
|
|
36
|
+
const cid = CID.createV1(jsonCodec.code, hash);
|
|
37
|
+
await this.components.blockstore.put(cid, buf, options);
|
|
38
|
+
return cid;
|
|
39
|
+
}
|
|
40
|
+
async get(cid, options = {}) {
|
|
41
|
+
const buf = await this.components.blockstore.get(cid, options);
|
|
42
|
+
return jsonCodec.decode(buf);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create a {@link JSON} instance for use with {@link https://github.com/ipfs/helia Helia}
|
|
47
|
+
*/
|
|
48
|
+
export function json(helia) {
|
|
49
|
+
return new DefaultJSON(helia);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,SAAS,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AA+DjD,MAAM,WAAW;IACE,UAAU,CAAgB;IAE3C,YAAa,UAA0B;QACrC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,GAAG,CAAE,GAAQ,EAAE,UAA+B,EAAE;QACpD,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACzD,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAE9C,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QAEvD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,GAAG,CAAM,GAAQ,EAAE,UAA+B,EAAE;QACxD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAE9D,OAAO,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,IAAI,CAAE,KAA6B;IACjD,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,CAAA;AAC/B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@helia/json",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Add/get IPLD blocks containing json with your Helia node",
|
|
5
|
+
"license": "Apache-2.0 OR MIT",
|
|
6
|
+
"homepage": "https://github.com/ipfs/helia-json/tree/master/packages/strings#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ipfs/helia-json.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/ipfs/helia-json/issues"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"IPFS"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=16.0.0",
|
|
19
|
+
"npm": ">=7.0.0"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"types": "./dist/src/index.d.ts",
|
|
23
|
+
"files": [
|
|
24
|
+
"src",
|
|
25
|
+
"dist",
|
|
26
|
+
"!dist/test",
|
|
27
|
+
"!**/*.tsbuildinfo"
|
|
28
|
+
],
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/src/index.d.ts",
|
|
32
|
+
"import": "./dist/src/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"eslintConfig": {
|
|
36
|
+
"extends": "ipfs",
|
|
37
|
+
"parserOptions": {
|
|
38
|
+
"sourceType": "module"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"release": {
|
|
42
|
+
"branches": [
|
|
43
|
+
"main"
|
|
44
|
+
],
|
|
45
|
+
"plugins": [
|
|
46
|
+
[
|
|
47
|
+
"@semantic-release/commit-analyzer",
|
|
48
|
+
{
|
|
49
|
+
"preset": "conventionalcommits",
|
|
50
|
+
"releaseRules": [
|
|
51
|
+
{
|
|
52
|
+
"breaking": true,
|
|
53
|
+
"release": "major"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"revert": true,
|
|
57
|
+
"release": "patch"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"type": "feat",
|
|
61
|
+
"release": "minor"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"type": "fix",
|
|
65
|
+
"release": "patch"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"type": "docs",
|
|
69
|
+
"release": "patch"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"type": "test",
|
|
73
|
+
"release": "patch"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"type": "deps",
|
|
77
|
+
"release": "patch"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"scope": "no-release",
|
|
81
|
+
"release": false
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
"@semantic-release/release-notes-generator",
|
|
88
|
+
{
|
|
89
|
+
"preset": "conventionalcommits",
|
|
90
|
+
"presetConfig": {
|
|
91
|
+
"types": [
|
|
92
|
+
{
|
|
93
|
+
"type": "feat",
|
|
94
|
+
"section": "Features"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"type": "fix",
|
|
98
|
+
"section": "Bug Fixes"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"type": "chore",
|
|
102
|
+
"section": "Trivial Changes"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"type": "docs",
|
|
106
|
+
"section": "Documentation"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"type": "deps",
|
|
110
|
+
"section": "Dependencies"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"type": "test",
|
|
114
|
+
"section": "Tests"
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"@semantic-release/changelog",
|
|
121
|
+
"@semantic-release/npm",
|
|
122
|
+
"@semantic-release/github",
|
|
123
|
+
"@semantic-release/git"
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
"scripts": {
|
|
127
|
+
"clean": "aegir clean",
|
|
128
|
+
"lint": "aegir lint",
|
|
129
|
+
"dep-check": "aegir dep-check",
|
|
130
|
+
"build": "aegir build",
|
|
131
|
+
"docs": "aegir docs",
|
|
132
|
+
"test": "aegir test",
|
|
133
|
+
"test:chrome": "aegir test -t browser --cov",
|
|
134
|
+
"test:chrome-webworker": "aegir test -t webworker",
|
|
135
|
+
"test:firefox": "aegir test -t browser -- --browser firefox",
|
|
136
|
+
"test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
|
|
137
|
+
"test:node": "aegir test -t node --cov",
|
|
138
|
+
"test:electron-main": "aegir test -t electron-main",
|
|
139
|
+
"release": "aegir release"
|
|
140
|
+
},
|
|
141
|
+
"dependencies": {
|
|
142
|
+
"@helia/interface": "^1.0.0",
|
|
143
|
+
"@libp2p/interfaces": "^3.3.1",
|
|
144
|
+
"interface-blockstore": "^5.0.0",
|
|
145
|
+
"multiformats": "^11.0.1",
|
|
146
|
+
"progress-events": "^1.0.0",
|
|
147
|
+
"uint8arrays": "^4.0.3"
|
|
148
|
+
},
|
|
149
|
+
"devDependencies": {
|
|
150
|
+
"aegir": "^39.0.3",
|
|
151
|
+
"blockstore-core": "^4.0.1"
|
|
152
|
+
},
|
|
153
|
+
"typedoc": {
|
|
154
|
+
"entryPoint": "./src/index.ts"
|
|
155
|
+
}
|
|
156
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* `@helia/json` makes working with strings {@link https://github.com/ipfs/helia Helia} simple & straightforward.
|
|
5
|
+
*
|
|
6
|
+
* See the {@link Strings Strings interface} for all available operations.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createHelia } from 'helia'
|
|
12
|
+
* import { json } from '@helia/json'
|
|
13
|
+
* import { CID } from 'multiformats/cid'
|
|
14
|
+
*
|
|
15
|
+
* const j = json(helia)
|
|
16
|
+
* const cid = await j.put({
|
|
17
|
+
* hello: 'world'
|
|
18
|
+
* })
|
|
19
|
+
* const obj = await j.get(cid)
|
|
20
|
+
*
|
|
21
|
+
* console.info(obj)
|
|
22
|
+
* // { hello: 'world' }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { CID } from 'multiformats/cid'
|
|
27
|
+
import * as jsonCodec from 'multiformats/codecs/json'
|
|
28
|
+
import { sha256 } from 'multiformats/hashes/sha2'
|
|
29
|
+
import type { Blocks, GetBlockProgressEvents, PutBlockProgressEvents } from '@helia/interface/blocks'
|
|
30
|
+
import type { AbortOptions } from '@libp2p/interfaces'
|
|
31
|
+
import type { BlockCodec } from 'multiformats/codecs/interface'
|
|
32
|
+
import type { MultihashHasher } from 'multiformats/hashes/interface'
|
|
33
|
+
import type { ProgressOptions } from 'progress-events'
|
|
34
|
+
|
|
35
|
+
export interface JSONComponents {
|
|
36
|
+
blockstore: Blocks
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface AddOptions extends AbortOptions, ProgressOptions<PutBlockProgressEvents> {
|
|
40
|
+
hasher: MultihashHasher
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface GetOptions extends AbortOptions, ProgressOptions<GetBlockProgressEvents> {
|
|
44
|
+
codec: BlockCodec<any, unknown>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The JSON interface provides a simple and intuitive way to add/get objects
|
|
49
|
+
* with your Helia node and is a great place to start learning about IPFS.
|
|
50
|
+
*/
|
|
51
|
+
export interface JSON {
|
|
52
|
+
/**
|
|
53
|
+
* Add an object to your Helia node and get a CID that refers to the block the
|
|
54
|
+
* object has been stored as.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
*
|
|
58
|
+
* ```typescript
|
|
59
|
+
* import { json } from '@helia/json'
|
|
60
|
+
*
|
|
61
|
+
* const j = json(helia)
|
|
62
|
+
* const cid = await str.add({ hello: 'world' })
|
|
63
|
+
*
|
|
64
|
+
* console.info(cid)
|
|
65
|
+
* // CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea)
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
add: (str: unknown, options?: Partial<AddOptions>) => Promise<CID>
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get an object from your Helia node, either previously added to it or to
|
|
72
|
+
* another node on the network.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
*
|
|
76
|
+
* ```typescript
|
|
77
|
+
* import { json } from '@helia/json'
|
|
78
|
+
* import { CID } from 'multiformats/cid'
|
|
79
|
+
*
|
|
80
|
+
* const j = json(helia)
|
|
81
|
+
* const cid = CID.parse('bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea')
|
|
82
|
+
* const obj = await j.get(cid)
|
|
83
|
+
*
|
|
84
|
+
* console.info(obj)
|
|
85
|
+
* // { hello: 'world' }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
get: <T> (cid: CID, options?: Partial<GetOptions>) => Promise<T>
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
class DefaultJSON implements JSON {
|
|
92
|
+
private readonly components: JSONComponents
|
|
93
|
+
|
|
94
|
+
constructor (components: JSONComponents) {
|
|
95
|
+
this.components = components
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async add (obj: any, options: Partial<AddOptions> = {}): Promise<CID> {
|
|
99
|
+
const buf = jsonCodec.encode(obj)
|
|
100
|
+
const hash = await (options.hasher ?? sha256).digest(buf)
|
|
101
|
+
const cid = CID.createV1(jsonCodec.code, hash)
|
|
102
|
+
|
|
103
|
+
await this.components.blockstore.put(cid, buf, options)
|
|
104
|
+
|
|
105
|
+
return cid
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async get <T> (cid: CID, options: Partial<GetOptions> = {}): Promise<T> {
|
|
109
|
+
const buf = await this.components.blockstore.get(cid, options)
|
|
110
|
+
|
|
111
|
+
return jsonCodec.decode(buf)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Create a {@link JSON} instance for use with {@link https://github.com/ipfs/helia Helia}
|
|
117
|
+
*/
|
|
118
|
+
export function json (helia: { blockstore: Blocks }): JSON {
|
|
119
|
+
return new DefaultJSON(helia)
|
|
120
|
+
}
|