@helia/ipns 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 +25 -0
- package/dist/src/index.d.ts +124 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +192 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/routing/dht.d.ts +18 -0
- package/dist/src/routing/dht.d.ts.map +1 -0
- package/dist/src/routing/dht.js +65 -0
- package/dist/src/routing/dht.js.map +1 -0
- package/dist/src/routing/index.d.ts +17 -0
- package/dist/src/routing/index.d.ts.map +1 -0
- package/dist/src/routing/index.js +3 -0
- package/dist/src/routing/index.js.map +1 -0
- package/dist/src/routing/local-store.d.ts +15 -0
- package/dist/src/routing/local-store.d.ts.map +1 -0
- package/dist/src/routing/local-store.js +48 -0
- package/dist/src/routing/local-store.js.map +1 -0
- package/dist/src/routing/pubsub.d.ts +20 -0
- package/dist/src/routing/pubsub.d.ts.map +1 -0
- package/dist/src/routing/pubsub.js +150 -0
- package/dist/src/routing/pubsub.js.map +1 -0
- package/dist/src/utils/resolve-dns-link.browser.d.ts +6 -0
- package/dist/src/utils/resolve-dns-link.browser.d.ts.map +1 -0
- package/dist/src/utils/resolve-dns-link.browser.js +46 -0
- package/dist/src/utils/resolve-dns-link.browser.js.map +1 -0
- package/dist/src/utils/resolve-dns-link.d.ts +3 -0
- package/dist/src/utils/resolve-dns-link.d.ts.map +1 -0
- package/dist/src/utils/resolve-dns-link.js +54 -0
- package/dist/src/utils/resolve-dns-link.js.map +1 -0
- package/dist/src/utils/tlru.d.ts +15 -0
- package/dist/src/utils/tlru.d.ts.map +1 -0
- package/dist/src/utils/tlru.js +39 -0
- package/dist/src/utils/tlru.js.map +1 -0
- package/package.json +191 -0
- package/src/index.ts +296 -0
- package/src/routing/dht.ts +85 -0
- package/src/routing/index.ts +26 -0
- package/src/routing/local-store.ts +63 -0
- package/src/routing/pubsub.ts +195 -0
- package/src/utils/resolve-dns-link.browser.ts +61 -0
- package/src/utils/resolve-dns-link.ts +65 -0
- package/src/utils/tlru.ts +52 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var _PubSubRouting_instances, _PubSubRouting_processPubSubMessage;
|
|
7
|
+
import { peerIdToRoutingKey } from 'ipns';
|
|
8
|
+
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
|
|
9
|
+
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
|
10
|
+
import { logger } from '@libp2p/logger';
|
|
11
|
+
import { CodeError } from '@libp2p/interfaces/errors';
|
|
12
|
+
import { localStore } from './local-store.js';
|
|
13
|
+
import { ipnsValidator } from 'ipns/validator';
|
|
14
|
+
import { ipnsSelector } from 'ipns/selector';
|
|
15
|
+
import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
|
|
16
|
+
import { CustomProgressEvent } from 'progress-events';
|
|
17
|
+
const log = logger('helia:ipns:routing:pubsub');
|
|
18
|
+
/**
|
|
19
|
+
* This IPNS routing receives IPNS record updates via dedicated
|
|
20
|
+
* pubsub topic.
|
|
21
|
+
*
|
|
22
|
+
* Note we must first be subscribed to the topic in order to receive
|
|
23
|
+
* updated records, so the first call to `.get` should be expected
|
|
24
|
+
* to fail!
|
|
25
|
+
*/
|
|
26
|
+
class PubSubRouting {
|
|
27
|
+
constructor(components) {
|
|
28
|
+
_PubSubRouting_instances.add(this);
|
|
29
|
+
this.subscriptions = [];
|
|
30
|
+
this.localStore = localStore(components.datastore);
|
|
31
|
+
this.peerId = components.libp2p.peerId;
|
|
32
|
+
this.pubsub = components.libp2p.pubsub;
|
|
33
|
+
this.pubsub.addEventListener('message', (evt) => {
|
|
34
|
+
const message = evt.detail;
|
|
35
|
+
if (!this.subscriptions.includes(message.topic)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
__classPrivateFieldGet(this, _PubSubRouting_instances, "m", _PubSubRouting_processPubSubMessage).call(this, message).catch(err => {
|
|
39
|
+
log.error('Error processing message', err);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Put a value to the pubsub datastore indexed by the received key properly encoded
|
|
45
|
+
*/
|
|
46
|
+
async put(routingKey, marshaledRecord, options = {}) {
|
|
47
|
+
try {
|
|
48
|
+
const topic = keyToTopic(routingKey);
|
|
49
|
+
log('publish value for topic %s', topic);
|
|
50
|
+
const result = await this.pubsub.publish(topic, marshaledRecord);
|
|
51
|
+
log('published record on topic %s to %d recipients', topic, result.recipients);
|
|
52
|
+
options.onProgress?.(new CustomProgressEvent('ipns:pubsub:publish', { topic, result }));
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
options.onProgress?.(new CustomProgressEvent('ipns:pubsub:error', err));
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get a value from the pubsub datastore indexed by the received key properly encoded.
|
|
61
|
+
* Also, the identifier topic is subscribed to and the pubsub datastore records will be
|
|
62
|
+
* updated once new publishes occur
|
|
63
|
+
*/
|
|
64
|
+
async get(routingKey, options = {}) {
|
|
65
|
+
try {
|
|
66
|
+
const topic = keyToTopic(routingKey);
|
|
67
|
+
// ensure we are subscribed to topic
|
|
68
|
+
if (!this.pubsub.getTopics().includes(topic)) {
|
|
69
|
+
log('add subscription for topic', topic);
|
|
70
|
+
this.pubsub.subscribe(topic);
|
|
71
|
+
this.subscriptions.push(topic);
|
|
72
|
+
options.onProgress?.(new CustomProgressEvent('ipns:pubsub:subscribe', { topic }));
|
|
73
|
+
}
|
|
74
|
+
// chain through to local store
|
|
75
|
+
return await this.localStore.get(routingKey, options);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
options.onProgress?.(new CustomProgressEvent('ipns:pubsub:error', err));
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get pubsub subscriptions related to ipns
|
|
84
|
+
*/
|
|
85
|
+
getSubscriptions() {
|
|
86
|
+
return this.subscriptions;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Cancel pubsub subscriptions related to ipns
|
|
90
|
+
*/
|
|
91
|
+
cancel(key) {
|
|
92
|
+
const routingKey = peerIdToRoutingKey(key);
|
|
93
|
+
const topic = keyToTopic(routingKey);
|
|
94
|
+
// Not found topic
|
|
95
|
+
if (!this.subscriptions.includes(topic)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
this.pubsub.unsubscribe(topic);
|
|
99
|
+
this.subscriptions = this.subscriptions.filter(t => t !== topic);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
_PubSubRouting_instances = new WeakSet(), _PubSubRouting_processPubSubMessage = async function _PubSubRouting_processPubSubMessage(message) {
|
|
103
|
+
log('message received for topic', message.topic);
|
|
104
|
+
if (message.type !== 'signed') {
|
|
105
|
+
log.error('unsigned message received, this module can only work with signed messages');
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (message.from.equals(this.peerId)) {
|
|
109
|
+
log('not storing record from self');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const routingKey = topicToKey(message.topic);
|
|
113
|
+
await ipnsValidator(routingKey, message.data);
|
|
114
|
+
if (await this.localStore.has(routingKey)) {
|
|
115
|
+
const currentRecord = await this.localStore.get(routingKey);
|
|
116
|
+
if (uint8ArrayEquals(currentRecord, message.data)) {
|
|
117
|
+
log('not storing record as we already have it');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const records = [currentRecord, message.data];
|
|
121
|
+
const index = ipnsSelector(routingKey, records);
|
|
122
|
+
if (index === 0) {
|
|
123
|
+
log('not storing record as the one we have is better');
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
await this.localStore.put(routingKey, message.data);
|
|
128
|
+
};
|
|
129
|
+
const PUBSUB_NAMESPACE = '/record/';
|
|
130
|
+
/**
|
|
131
|
+
* converts a binary record key to a pubsub topic key
|
|
132
|
+
*/
|
|
133
|
+
function keyToTopic(key) {
|
|
134
|
+
const b64url = uint8ArrayToString(key, 'base64url');
|
|
135
|
+
return `${PUBSUB_NAMESPACE}${b64url}`;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* converts a pubsub topic key to a binary record key
|
|
139
|
+
*/
|
|
140
|
+
function topicToKey(topic) {
|
|
141
|
+
if (topic.substring(0, PUBSUB_NAMESPACE.length) !== PUBSUB_NAMESPACE) {
|
|
142
|
+
throw new CodeError('topic received is not from a record', 'ERR_TOPIC_IS_NOT_FROM_RECORD_NAMESPACE');
|
|
143
|
+
}
|
|
144
|
+
const key = topic.substring(PUBSUB_NAMESPACE.length);
|
|
145
|
+
return uint8ArrayFromString(key, 'base64url');
|
|
146
|
+
}
|
|
147
|
+
export function pubsub(components) {
|
|
148
|
+
return new PubSubRouting(components);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=pubsub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pubsub.js","sourceRoot":"","sources":["../../../src/routing/pubsub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AbortOptions } from '@libp2p/interfaces';
|
|
2
|
+
export interface ResolveDnsLinkOptions extends AbortOptions {
|
|
3
|
+
nocache?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function resolveDnslink(fqdn: string, opts?: ResolveDnsLinkOptions): Promise<string>;
|
|
6
|
+
//# sourceMappingURL=resolve-dns-link.browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-dns-link.browser.d.ts","sourceRoot":"","sources":["../../../src/utils/resolve-dns-link.browser.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAoBtD,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IACzD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAsB,cAAc,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAgCrG"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* eslint-env browser */
|
|
2
|
+
import { TLRU } from './tlru.js';
|
|
3
|
+
import PQueue from 'p-queue';
|
|
4
|
+
// Avoid sending multiple queries for the same hostname by caching results
|
|
5
|
+
const cache = new TLRU(1000);
|
|
6
|
+
// TODO: /api/v0/dns does not return TTL yet: https://github.com/ipfs/go-ipfs/issues/5884
|
|
7
|
+
// However we know browsers themselves cache DNS records for at least 1 minute,
|
|
8
|
+
// which acts a provisional default ttl: https://stackoverflow.com/a/36917902/11518426
|
|
9
|
+
const ttl = 60 * 1000;
|
|
10
|
+
// browsers limit concurrent connections per host,
|
|
11
|
+
// we don't want preload calls to exhaust the limit (~6)
|
|
12
|
+
const httpQueue = new PQueue({ concurrency: 4 });
|
|
13
|
+
const ipfsPath = (response) => {
|
|
14
|
+
if (response.Path != null) {
|
|
15
|
+
return response.Path;
|
|
16
|
+
}
|
|
17
|
+
throw new Error(response.Message);
|
|
18
|
+
};
|
|
19
|
+
export async function resolveDnslink(fqdn, opts = {}) {
|
|
20
|
+
const resolve = async (fqdn, opts = {}) => {
|
|
21
|
+
// @ts-expect-error - URLSearchParams does not take boolean options, only strings
|
|
22
|
+
const searchParams = new URLSearchParams(opts);
|
|
23
|
+
searchParams.set('arg', fqdn);
|
|
24
|
+
// try cache first
|
|
25
|
+
const query = searchParams.toString();
|
|
26
|
+
if (opts.nocache !== true && cache.has(query)) {
|
|
27
|
+
const response = cache.get(query);
|
|
28
|
+
if (response != null) {
|
|
29
|
+
return ipfsPath(response);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// fallback to delegated DNS resolver
|
|
33
|
+
const response = await httpQueue.add(async () => {
|
|
34
|
+
// Delegated HTTP resolver sending DNSLink queries to ipfs.io
|
|
35
|
+
// TODO: replace hardcoded host with configurable DNS over HTTPS: https://github.com/ipfs/js-ipfs/issues/2212
|
|
36
|
+
const res = await fetch(`https://ipfs.io/api/v0/dns?${searchParams}`);
|
|
37
|
+
const query = new URL(res.url).search.slice(1);
|
|
38
|
+
const json = await res.json();
|
|
39
|
+
cache.set(query, json, ttl);
|
|
40
|
+
return json;
|
|
41
|
+
});
|
|
42
|
+
return ipfsPath(response);
|
|
43
|
+
};
|
|
44
|
+
return await resolve(fqdn, opts);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=resolve-dns-link.browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-dns-link.browser.js","sourceRoot":"","sources":["../../../src/utils/resolve-dns-link.browser.ts"],"names":[],"mappings":"AAAA,wBAAwB;AAExB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,MAAM,MAAM,SAAS,CAAA;AAG5B,0EAA0E;AAC1E,MAAM,KAAK,GAAG,IAAI,IAAI,CAAoC,IAAI,CAAC,CAAA;AAC/D,yFAAyF;AACzF,+EAA+E;AAC/E,sFAAsF;AACtF,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,CAAA;AAErB,kDAAkD;AAClD,wDAAwD;AACxD,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;AAEhD,MAAM,QAAQ,GAAG,CAAC,QAA2C,EAAU,EAAE;IACvE,IAAI,QAAQ,CAAC,IAAI,IAAI,IAAI,EAAE;QACzB,OAAO,QAAQ,CAAC,IAAI,CAAA;KACrB;IACD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AACnC,CAAC,CAAA;AAMD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAE,IAAY,EAAE,OAA8B,EAAE;IAClF,MAAM,OAAO,GAAG,KAAK,EAAE,IAAY,EAAE,OAA8B,EAAE,EAAmB,EAAE;QACxF,iFAAiF;QACjF,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;QAC9C,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAE7B,kBAAkB;QAClB,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAA;QACrC,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YAEjC,IAAI,QAAQ,IAAI,IAAI,EAAE;gBACpB,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAA;aAC1B;SACF;QAED,qCAAqC;QACrC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YAC9C,6DAA6D;YAC7D,6GAA6G;YAC7G,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAA;YACrE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAC9C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;YAC7B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;YAE3B,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;QAEF,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC3B,CAAC,CAAA;IAED,OAAO,MAAM,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-dns-link.d.ts","sourceRoot":"","sources":["../../../src/utils/resolve-dns-link.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAKtD,wBAAsB,cAAc,CAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import dns from 'dns';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
import * as isIPFS from 'is-ipfs';
|
|
4
|
+
const MAX_RECURSIVE_DEPTH = 32;
|
|
5
|
+
export async function resolveDnslink(domain, options = {}) {
|
|
6
|
+
return await recursiveResolveDnslink(domain, MAX_RECURSIVE_DEPTH, options);
|
|
7
|
+
}
|
|
8
|
+
async function recursiveResolveDnslink(domain, depth, options = {}) {
|
|
9
|
+
if (depth === 0) {
|
|
10
|
+
throw new Error('recursion limit exceeded');
|
|
11
|
+
}
|
|
12
|
+
let dnslinkRecord;
|
|
13
|
+
try {
|
|
14
|
+
dnslinkRecord = await resolve(domain);
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
// If the code is not ENOTFOUND or ERR_DNSLINK_NOT_FOUND or ENODATA then throw the error
|
|
18
|
+
if (err.code !== 'ENOTFOUND' && err.code !== 'ERR_DNSLINK_NOT_FOUND' && err.code !== 'ENODATA') {
|
|
19
|
+
throw err;
|
|
20
|
+
}
|
|
21
|
+
if (domain.startsWith('_dnslink.')) {
|
|
22
|
+
// The supplied domain contains a _dnslink component
|
|
23
|
+
// Check the non-_dnslink domain
|
|
24
|
+
dnslinkRecord = await resolve(domain.replace('_dnslink.', ''));
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// Check the _dnslink subdomain
|
|
28
|
+
const _dnslinkDomain = `_dnslink.${domain}`;
|
|
29
|
+
// If this throws then we propagate the error
|
|
30
|
+
dnslinkRecord = await resolve(_dnslinkDomain);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const result = dnslinkRecord.replace('dnslink=', '');
|
|
34
|
+
const domainOrCID = result.split('/')[2];
|
|
35
|
+
const isIPFSCID = isIPFS.cid(domainOrCID);
|
|
36
|
+
if (isIPFSCID || depth === 0) {
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
return await recursiveResolveDnslink(domainOrCID, depth - 1, options);
|
|
40
|
+
}
|
|
41
|
+
async function resolve(domain, options = {}) {
|
|
42
|
+
const DNSLINK_REGEX = /^dnslink=.+$/;
|
|
43
|
+
const records = await promisify(dns.resolveTxt)(domain);
|
|
44
|
+
const dnslinkRecords = records.reduce((rs, r) => rs.concat(r), [])
|
|
45
|
+
.filter(record => DNSLINK_REGEX.test(record));
|
|
46
|
+
const dnslinkRecord = dnslinkRecords[0];
|
|
47
|
+
// we now have dns text entries as an array of strings
|
|
48
|
+
// only records passing the DNSLINK_REGEX text are included
|
|
49
|
+
if (dnslinkRecord == null) {
|
|
50
|
+
throw new Error(`No dnslink records found for domain: ${domain}`);
|
|
51
|
+
}
|
|
52
|
+
return dnslinkRecord;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=resolve-dns-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-dns-link.js","sourceRoot":"","sources":["../../../src/utils/resolve-dns-link.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAEhC,OAAO,KAAK,MAAM,MAAM,SAAS,CAAA;AAEjC,MAAM,mBAAmB,GAAG,EAAE,CAAA;AAE9B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAE,MAAc,EAAE,UAAwB,EAAE;IAC9E,OAAO,MAAM,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAA;AAC5E,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAE,MAAc,EAAE,KAAa,EAAE,UAAwB,EAAE;IAC/F,IAAI,KAAK,KAAK,CAAC,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;KAC5C;IAED,IAAI,aAAa,CAAA;IAEjB,IAAI;QACF,aAAa,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;KACtC;IAAC,OAAO,GAAQ,EAAE;QACjB,wFAAwF;QACxF,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,uBAAuB,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE;YAC9F,MAAM,GAAG,CAAA;SACV;QAED,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE;YAClC,oDAAoD;YACpD,gCAAgC;YAChC,aAAa,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAA;SAC/D;aAAM;YACL,+BAA+B;YAC/B,MAAM,cAAc,GAAG,YAAY,MAAM,EAAE,CAAA;YAC3C,6CAA6C;YAC7C,aAAa,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,CAAA;SAC9C;KACF;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IACpD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAEzC,IAAI,SAAS,IAAI,KAAK,KAAK,CAAC,EAAE;QAC5B,OAAO,MAAM,CAAA;KACd;IAED,OAAO,MAAM,uBAAuB,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;AACvE,CAAC;AAED,KAAK,UAAU,OAAO,CAAE,MAAc,EAAE,UAAwB,EAAE;IAChE,MAAM,aAAa,GAAG,cAAc,CAAA;IACpC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;IACvD,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SAC/D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;IAE/C,MAAM,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;IAEvC,sDAAsD;IACtD,2DAA2D;IAC3D,IAAI,aAAa,IAAI,IAAI,EAAE;QACzB,MAAM,IAAI,KAAK,CAAC,wCAAwC,MAAM,EAAE,CAAC,CAAA;KAClE;IAED,OAAO,aAAa,CAAA;AACtB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time Aware Least Recent Used Cache
|
|
3
|
+
*
|
|
4
|
+
* @see https://arxiv.org/pdf/1801.00390
|
|
5
|
+
*/
|
|
6
|
+
export declare class TLRU<T> {
|
|
7
|
+
private readonly lru;
|
|
8
|
+
constructor(maxSize: number);
|
|
9
|
+
get(key: string): T | undefined;
|
|
10
|
+
set(key: string, value: T, ttl: number): void;
|
|
11
|
+
has(key: string): boolean;
|
|
12
|
+
remove(key: string): void;
|
|
13
|
+
clear(): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=tlru.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tlru.d.ts","sourceRoot":"","sources":["../../../src/utils/tlru.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,qBAAa,IAAI,CAAC,CAAC;IACjB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA4B;gBAEnC,OAAO,EAAE,MAAM;IAI5B,GAAG,CAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAgBhC,GAAG,CAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAI9C,GAAG,CAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAU1B,MAAM,CAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAI1B,KAAK,IAAK,IAAI;CAGf"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import hashlru from 'hashlru';
|
|
2
|
+
/**
|
|
3
|
+
* Time Aware Least Recent Used Cache
|
|
4
|
+
*
|
|
5
|
+
* @see https://arxiv.org/pdf/1801.00390
|
|
6
|
+
*/
|
|
7
|
+
export class TLRU {
|
|
8
|
+
constructor(maxSize) {
|
|
9
|
+
this.lru = hashlru(maxSize);
|
|
10
|
+
}
|
|
11
|
+
get(key) {
|
|
12
|
+
const value = this.lru.get(key);
|
|
13
|
+
if (value != null) {
|
|
14
|
+
if (value.expire != null && value.expire < Date.now()) {
|
|
15
|
+
this.lru.remove(key);
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
return value.value;
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
set(key, value, ttl) {
|
|
23
|
+
this.lru.set(key, { value, expire: Date.now() + ttl });
|
|
24
|
+
}
|
|
25
|
+
has(key) {
|
|
26
|
+
const value = this.get(key);
|
|
27
|
+
if (value != null) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
remove(key) {
|
|
33
|
+
this.lru.remove(key);
|
|
34
|
+
}
|
|
35
|
+
clear() {
|
|
36
|
+
this.lru.clear();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=tlru.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tlru.js","sourceRoot":"","sources":["../../../src/utils/tlru.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B;;;;GAIG;AACH,MAAM,OAAO,IAAI;IAGf,YAAa,OAAe;QAC1B,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7B,CAAC;IAED,GAAG,CAAE,GAAW;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE/B,IAAI,KAAK,IAAI,IAAI,EAAE;YACjB,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE;gBACrD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAEpB,OAAO,SAAS,CAAA;aACjB;YAED,OAAO,KAAK,CAAC,KAAK,CAAA;SACnB;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,GAAG,CAAE,GAAW,EAAE,KAAQ,EAAE,GAAW;QACrC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,GAAG,CAAE,GAAW;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE3B,IAAI,KAAK,IAAI,IAAI,EAAE;YACjB,OAAO,IAAI,CAAA;SACZ;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,CAAE,GAAW;QACjB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACtB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAA;IAClB,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@helia/ipns",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "An implementation of IPNS for Helia",
|
|
5
|
+
"license": "Apache-2.0 OR MIT",
|
|
6
|
+
"homepage": "https://github.com/ipfs/helia-ipns/tree/master/packages/ipns#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ipfs/helia-ipns.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/ipfs/helia-ipns/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
|
+
"typesVersions": {
|
|
24
|
+
"*": {
|
|
25
|
+
"*": [
|
|
26
|
+
"*",
|
|
27
|
+
"dist/*",
|
|
28
|
+
"dist/src/*",
|
|
29
|
+
"dist/src/*/index"
|
|
30
|
+
],
|
|
31
|
+
"src/*": [
|
|
32
|
+
"*",
|
|
33
|
+
"dist/*",
|
|
34
|
+
"dist/src/*",
|
|
35
|
+
"dist/src/*/index"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"src",
|
|
41
|
+
"dist",
|
|
42
|
+
"!dist/test",
|
|
43
|
+
"!**/*.tsbuildinfo"
|
|
44
|
+
],
|
|
45
|
+
"exports": {
|
|
46
|
+
".": {
|
|
47
|
+
"types": "./dist/src/index.d.ts",
|
|
48
|
+
"import": "./dist/src/index.js"
|
|
49
|
+
},
|
|
50
|
+
"./routing": {
|
|
51
|
+
"types": "./dist/src/routing/index.d.ts",
|
|
52
|
+
"import": "./dist/src/routing/index.js"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"eslintConfig": {
|
|
56
|
+
"extends": "ipfs",
|
|
57
|
+
"parserOptions": {
|
|
58
|
+
"sourceType": "module"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"release": {
|
|
62
|
+
"branches": [
|
|
63
|
+
"main"
|
|
64
|
+
],
|
|
65
|
+
"plugins": [
|
|
66
|
+
[
|
|
67
|
+
"@semantic-release/commit-analyzer",
|
|
68
|
+
{
|
|
69
|
+
"preset": "conventionalcommits",
|
|
70
|
+
"releaseRules": [
|
|
71
|
+
{
|
|
72
|
+
"breaking": true,
|
|
73
|
+
"release": "major"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"revert": true,
|
|
77
|
+
"release": "patch"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"type": "feat",
|
|
81
|
+
"release": "minor"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"type": "fix",
|
|
85
|
+
"release": "patch"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"type": "docs",
|
|
89
|
+
"release": "patch"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"type": "test",
|
|
93
|
+
"release": "patch"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"type": "deps",
|
|
97
|
+
"release": "patch"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"scope": "no-release",
|
|
101
|
+
"release": false
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
[
|
|
107
|
+
"@semantic-release/release-notes-generator",
|
|
108
|
+
{
|
|
109
|
+
"preset": "conventionalcommits",
|
|
110
|
+
"presetConfig": {
|
|
111
|
+
"types": [
|
|
112
|
+
{
|
|
113
|
+
"type": "feat",
|
|
114
|
+
"section": "Features"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "fix",
|
|
118
|
+
"section": "Bug Fixes"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"type": "chore",
|
|
122
|
+
"section": "Trivial Changes"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"type": "docs",
|
|
126
|
+
"section": "Documentation"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"type": "deps",
|
|
130
|
+
"section": "Dependencies"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"type": "test",
|
|
134
|
+
"section": "Tests"
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
"@semantic-release/changelog",
|
|
141
|
+
"@semantic-release/npm",
|
|
142
|
+
"@semantic-release/github",
|
|
143
|
+
"@semantic-release/git"
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
"scripts": {
|
|
147
|
+
"clean": "aegir clean",
|
|
148
|
+
"lint": "aegir lint",
|
|
149
|
+
"dep-check": "aegir dep-check",
|
|
150
|
+
"build": "aegir build",
|
|
151
|
+
"docs": "aegir docs",
|
|
152
|
+
"test": "aegir test",
|
|
153
|
+
"test:chrome": "aegir test -t browser --cov",
|
|
154
|
+
"test:chrome-webworker": "aegir test -t webworker",
|
|
155
|
+
"test:firefox": "aegir test -t browser -- --browser firefox",
|
|
156
|
+
"test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
|
|
157
|
+
"test:node": "aegir test -t node --cov",
|
|
158
|
+
"test:electron-main": "aegir test -t electron-main",
|
|
159
|
+
"release": "aegir release"
|
|
160
|
+
},
|
|
161
|
+
"dependencies": {
|
|
162
|
+
"@helia/interface": "next",
|
|
163
|
+
"@libp2p/interface-dht": "^2.0.1",
|
|
164
|
+
"@libp2p/interface-peer-id": "^2.0.1",
|
|
165
|
+
"@libp2p/interface-pubsub": "^3.0.6",
|
|
166
|
+
"@libp2p/interfaces": "^3.3.1",
|
|
167
|
+
"@libp2p/logger": "^2.0.5",
|
|
168
|
+
"@libp2p/peer-id": "^2.0.1",
|
|
169
|
+
"@libp2p/record": "^3.0.0",
|
|
170
|
+
"hashlru": "^2.3.0",
|
|
171
|
+
"interface-datastore": "^7.0.4",
|
|
172
|
+
"ipns": "^5.0.1",
|
|
173
|
+
"is-ipfs": "^8.0.1",
|
|
174
|
+
"multiformats": "^11.0.1",
|
|
175
|
+
"p-queue": "^7.3.0",
|
|
176
|
+
"progress-events": "^1.0.0",
|
|
177
|
+
"uint8arrays": "^4.0.3"
|
|
178
|
+
},
|
|
179
|
+
"devDependencies": {
|
|
180
|
+
"@libp2p/peer-id-factory": "^2.0.1",
|
|
181
|
+
"aegir": "^38.1.0",
|
|
182
|
+
"datastore-core": "^8.0.4",
|
|
183
|
+
"sinon": "^15.0.1"
|
|
184
|
+
},
|
|
185
|
+
"browser": {
|
|
186
|
+
"./dist/src/utils/resolve-dns-link.js": "./dist/src/utils/resolve-dns-link.browser.js"
|
|
187
|
+
},
|
|
188
|
+
"typedoc": {
|
|
189
|
+
"entryPoint": "./src/index.ts"
|
|
190
|
+
}
|
|
191
|
+
}
|