@ceramicnetwork/core
Version:
Typescript implementation of the Ceramic protocol
154 lines • 8.98 kB
JavaScript
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _ReconApi_config, _ReconApi_logger, _ReconApi_sendRequest, _ReconApi_url, _ReconApi_initialized, _ReconApi_pollInterval, _ReconApi_eventsSubscription, _ReconApi_feed$, _ReconApi_stopSignal;
import { Subject, defer, concatMap, expand, of, retry, timer, Observable, filter, takeUntil, } from 'rxjs';
import { fetchJson, } from '@ceramicnetwork/common';
import { Model } from '@ceramicnetwork/stream-model';
import { CID } from 'multiformats/cid';
const DEFAULT_POLL_INTERVAL = 1000;
const FEED_LIMIT = 1000;
export class ReconApi extends Observable {
constructor(config, logger, sendRequest = fetchJson, pollInterval = DEFAULT_POLL_INTERVAL) {
super((subscriber) => {
return __classPrivateFieldGet(this, _ReconApi_feed$, "f").subscribe(subscriber);
});
_ReconApi_config.set(this, void 0);
_ReconApi_logger.set(this, void 0);
_ReconApi_sendRequest.set(this, void 0);
_ReconApi_url.set(this, void 0);
_ReconApi_initialized.set(this, false);
_ReconApi_pollInterval.set(this, void 0);
_ReconApi_eventsSubscription.set(this, void 0);
_ReconApi_feed$.set(this, new Subject());
_ReconApi_stopSignal.set(this, new Subject());
__classPrivateFieldSet(this, _ReconApi_config, config, "f");
__classPrivateFieldSet(this, _ReconApi_logger, logger, "f");
__classPrivateFieldSet(this, _ReconApi_sendRequest, sendRequest, "f");
__classPrivateFieldSet(this, _ReconApi_pollInterval, pollInterval, "f");
}
async init(initialCursor = '', initialInterests = []) {
if (__classPrivateFieldGet(this, _ReconApi_initialized, "f")) {
return;
}
__classPrivateFieldSet(this, _ReconApi_initialized, true, "f");
if (!this.enabled) {
return;
}
__classPrivateFieldSet(this, _ReconApi_url, await __classPrivateFieldGet(this, _ReconApi_config, "f").url, "f");
await this.verifyNetwork();
await this.registerInterest(Model.MODEL);
for (const interest of initialInterests) {
await this.registerInterest(interest);
}
if (__classPrivateFieldGet(this, _ReconApi_config, "f").feedEnabled) {
__classPrivateFieldSet(this, _ReconApi_eventsSubscription, this.createSubscription(initialCursor).subscribe(__classPrivateFieldGet(this, _ReconApi_feed$, "f")), "f");
}
}
async verifyNetwork() {
let response;
try {
response = await __classPrivateFieldGet(this, _ReconApi_sendRequest, "f").call(this, __classPrivateFieldGet(this, _ReconApi_url, "f") + '/ceramic/config/network', {
method: 'GET',
});
}
catch (err) {
__classPrivateFieldGet(this, _ReconApi_logger, "f").warn(`Recon: failed to verify network with error ${err}. This is likely due to an older version of ceramic-one and you should upgrade.`);
return;
}
if (response?.name) {
if (!response.name.includes(__classPrivateFieldGet(this, _ReconApi_config, "f").network)) {
throw new Error(`Recon: failed to verify network as js-ceramic is using ${__classPrivateFieldGet(this, _ReconApi_config, "f").network} but ceramic-one is on ${response.name}. Pass --network to the js-ceramic or ceramic-one daemon to make them match.`);
}
}
else {
__classPrivateFieldGet(this, _ReconApi_logger, "f").warn(`Recon: failed to verify network as nothing was found. This is likely due to an older version of ceramic-one and you should upgrade.`);
}
}
async registerInterest(model, controller) {
if (!this.enabled) {
throw new Error(`Recon: disabled, not registering interest in model ${model.toString()}`);
}
try {
const headers = { 'Content-Type': 'application/json' };
const body = { sep: 'model', sepValue: model.toString(), ...(controller && { controller }) };
await __classPrivateFieldGet(this, _ReconApi_sendRequest, "f").call(this, __classPrivateFieldGet(this, _ReconApi_url, "f") + `/ceramic/interests`, {
method: 'POST',
headers,
body,
});
__classPrivateFieldGet(this, _ReconApi_logger, "f").debug(`Recon: added interest for model ${model.toString()}`);
}
catch (err) {
__classPrivateFieldGet(this, _ReconApi_logger, "f").err(`Recon: failed to register interest in model ${model.toString()} with error ${err}`);
throw err;
}
}
async put(car, opts = {}) {
const cid = car.roots[0];
if (!this.enabled) {
__classPrivateFieldGet(this, _ReconApi_logger, "f").imp(`Recon: disabled, not putting event with cid ${cid.toString()}`);
return;
}
const body = {
data: car.toString(),
};
try {
await __classPrivateFieldGet(this, _ReconApi_sendRequest, "f").call(this, __classPrivateFieldGet(this, _ReconApi_url, "f") + '/ceramic/events', {
method: 'POST',
body,
signal: opts.signal,
});
__classPrivateFieldGet(this, _ReconApi_logger, "f").debug(`Recon: put event with cid ${cid.toString()}`);
}
catch (err) {
__classPrivateFieldGet(this, _ReconApi_logger, "f").err(`Recon: failed to add event with cid ${cid.toString()} with error ${err}`);
throw err;
}
}
get enabled() {
return __classPrivateFieldGet(this, _ReconApi_config, "f").enabled;
}
stop() {
__classPrivateFieldGet(this, _ReconApi_stopSignal, "f").next();
__classPrivateFieldGet(this, _ReconApi_stopSignal, "f").complete();
if (__classPrivateFieldGet(this, _ReconApi_eventsSubscription, "f")) {
__classPrivateFieldGet(this, _ReconApi_eventsSubscription, "f").unsubscribe();
}
__classPrivateFieldGet(this, _ReconApi_feed$, "f").complete();
}
createSubscription(initialCursor) {
return of({ events: [], cursor: initialCursor, first: true }).pipe(expand((prev) => {
return timer(prev.first ? 0 : __classPrivateFieldGet(this, _ReconApi_pollInterval, "f")).pipe(concatMap(() => defer(async () => {
const response = await __classPrivateFieldGet(this, _ReconApi_sendRequest, "f").call(this, __classPrivateFieldGet(this, _ReconApi_url, "f") + `/ceramic/feed/events?resumeAt=${prev.cursor}&limit=${FEED_LIMIT}`, {
method: 'GET',
});
return {
events: response.events.map(({ id }) => {
return {
cid: CID.parse(id),
data: null,
};
}),
cursor: response.resumeToken,
first: false,
};
}).pipe(retry({
delay: (err) => {
__classPrivateFieldGet(this, _ReconApi_logger, "f").warn(`Recon: event feed failed, due to error ${err}; attempting to retry in ${__classPrivateFieldGet(this, _ReconApi_pollInterval, "f")}ms`);
return timer(__classPrivateFieldGet(this, _ReconApi_pollInterval, "f"));
},
}))));
}), filter(({ events }) => events.length > 0), takeUntil(__classPrivateFieldGet(this, _ReconApi_stopSignal, "f")));
}
}
_ReconApi_config = new WeakMap(), _ReconApi_logger = new WeakMap(), _ReconApi_sendRequest = new WeakMap(), _ReconApi_url = new WeakMap(), _ReconApi_initialized = new WeakMap(), _ReconApi_pollInterval = new WeakMap(), _ReconApi_eventsSubscription = new WeakMap(), _ReconApi_feed$ = new WeakMap(), _ReconApi_stopSignal = new WeakMap();
//# sourceMappingURL=recon.js.map