@clioplaylists/clio 0.1.6 → 0.1.8
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/dist/.env +7 -0
- package/dist/api/health.js +3 -10
- package/dist/api/index.js +2 -39
- package/dist/api/util.js +6 -10
- package/dist/api/well-known.d.ts +3 -0
- package/dist/api/well-known.js +31 -0
- package/dist/auth-verifier.js +165 -273
- package/dist/client.js +8 -15
- package/dist/config.d.ts +2 -0
- package/dist/config.js +17 -23
- package/dist/context.d.ts +3 -0
- package/dist/context.js +6 -10
- package/dist/dataplane/client/hosts.d.ts +21 -0
- package/dist/dataplane/client/hosts.js +25 -0
- package/dist/dataplane/client/index.d.ts +11 -0
- package/dist/dataplane/client/index.js +97 -0
- package/dist/dataplane/client.js +25 -70
- package/dist/dataplane/index.js +2 -18
- package/dist/dataplane/server/background.js +8 -29
- package/dist/dataplane/server/db/database-schema.js +1 -2
- package/dist/dataplane/server/db/db.js +27 -103
- package/dist/dataplane/server/db/index.js +1 -17
- package/dist/dataplane/server/db/migrations/20230309T045948368Z-init.js +7 -11
- package/dist/dataplane/server/db/migrations/20230420T211446071Z-did-cache.js +2 -6
- package/dist/dataplane/server/db/migrations/index.js +2 -38
- package/dist/dataplane/server/db/migrations/provider.js +5 -17
- package/dist/dataplane/server/db/pagination.js +21 -37
- package/dist/dataplane/server/db/tables/actor-sync.js +1 -4
- package/dist/dataplane/server/db/tables/actor.js +1 -4
- package/dist/dataplane/server/db/tables/artist-list-item.js +1 -4
- package/dist/dataplane/server/db/tables/artist.js +1 -4
- package/dist/dataplane/server/db/tables/playlist-idea.js +1 -4
- package/dist/dataplane/server/db/tables/playlist-item.js +1 -4
- package/dist/dataplane/server/db/tables/playlist.js +1 -4
- package/dist/dataplane/server/db/tables/profile.js +1 -4
- package/dist/dataplane/server/db/tables/record.js +1 -4
- package/dist/dataplane/server/db/tables/song.js +1 -4
- package/dist/dataplane/server/db/types.js +1 -2
- package/dist/dataplane/server/db/util.js +18 -26
- package/dist/dataplane/server/index.js +17 -33
- package/dist/dataplane/server/indexing/index.js +39 -89
- package/dist/dataplane/server/indexing/plugins/playlist-idea.js +7 -44
- package/dist/dataplane/server/indexing/plugins/profile.js +5 -42
- package/dist/dataplane/server/indexing/processor.js +11 -29
- package/dist/dataplane/server/routes/identity.js +11 -13
- package/dist/dataplane/server/routes/index.js +10 -15
- package/dist/dataplane/server/routes/profile.js +9 -11
- package/dist/dataplane/server/routes/records.js +14 -51
- package/dist/dataplane/server/routes/sync.js +1 -3
- package/dist/dataplane/server/subscription.js +19 -47
- package/dist/error.js +5 -9
- package/dist/index.d.ts +2 -0
- package/dist/index.js +36 -90
- package/dist/lexicons/index.js +52 -227
- package/dist/lexicons/lexicons.js +5 -8
- package/dist/lexicons/types/com/atproto/admin/defs.js +27 -39
- package/dist/lexicons/types/com/atproto/admin/deleteAccount.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/disableAccountInvites.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/disableInviteCodes.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/enableAccountInvites.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/getAccountInfo.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/getAccountInfos.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/getInviteCodes.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/getSubjectStatus.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/searchAccounts.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/sendEmail.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/updateAccountEmail.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/updateAccountHandle.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/updateAccountPassword.js +1 -2
- package/dist/lexicons/types/com/atproto/admin/updateSubjectStatus.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/defs.js +7 -11
- package/dist/lexicons/types/com/atproto/identity/getRecommendedDidCredentials.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/refreshIdentity.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/requestPlcOperationSignature.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/resolveDid.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/resolveHandle.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/resolveIdentity.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/signPlcOperation.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/submitPlcOperation.js +1 -2
- package/dist/lexicons/types/com/atproto/identity/updateHandle.js +1 -2
- package/dist/lexicons/types/com/atproto/label/defs.js +27 -39
- package/dist/lexicons/types/com/atproto/label/queryLabels.js +1 -2
- package/dist/lexicons/types/com/atproto/label/subscribeLabels.js +12 -18
- package/dist/lexicons/types/com/atproto/lexicon/schema.js +7 -11
- package/dist/lexicons/types/com/atproto/moderation/createReport.js +1 -2
- package/dist/lexicons/types/com/atproto/moderation/defs.js +7 -10
- package/dist/lexicons/types/com/atproto/repo/applyWrites.js +32 -46
- package/dist/lexicons/types/com/atproto/repo/createRecord.js +1 -2
- package/dist/lexicons/types/com/atproto/repo/defs.js +7 -11
- package/dist/lexicons/types/com/atproto/repo/deleteRecord.js +1 -2
- package/dist/lexicons/types/com/atproto/repo/describeRepo.js +1 -2
- package/dist/lexicons/types/com/atproto/repo/getRecord.js +1 -2
- package/dist/lexicons/types/com/atproto/repo/importRepo.js +1 -2
- package/dist/lexicons/types/com/atproto/repo/listMissingBlobs.js +7 -11
- package/dist/lexicons/types/com/atproto/repo/listRecords.js +7 -11
- package/dist/lexicons/types/com/atproto/repo/putRecord.js +1 -2
- package/dist/lexicons/types/com/atproto/repo/strongRef.js +7 -11
- package/dist/lexicons/types/com/atproto/repo/uploadBlob.js +1 -2
- package/dist/lexicons/types/com/atproto/server/activateAccount.js +1 -2
- package/dist/lexicons/types/com/atproto/server/checkAccountStatus.js +1 -2
- package/dist/lexicons/types/com/atproto/server/confirmEmail.js +1 -2
- package/dist/lexicons/types/com/atproto/server/createAccount.js +1 -2
- package/dist/lexicons/types/com/atproto/server/createAppPassword.js +7 -11
- package/dist/lexicons/types/com/atproto/server/createInviteCode.js +1 -2
- package/dist/lexicons/types/com/atproto/server/createInviteCodes.js +7 -11
- package/dist/lexicons/types/com/atproto/server/createSession.js +1 -2
- package/dist/lexicons/types/com/atproto/server/deactivateAccount.js +1 -2
- package/dist/lexicons/types/com/atproto/server/defs.js +12 -18
- package/dist/lexicons/types/com/atproto/server/deleteAccount.js +1 -2
- package/dist/lexicons/types/com/atproto/server/deleteSession.js +1 -2
- package/dist/lexicons/types/com/atproto/server/describeServer.js +12 -18
- package/dist/lexicons/types/com/atproto/server/getAccountInviteCodes.js +1 -2
- package/dist/lexicons/types/com/atproto/server/getServiceAuth.js +1 -2
- package/dist/lexicons/types/com/atproto/server/getSession.js +1 -2
- package/dist/lexicons/types/com/atproto/server/listAppPasswords.js +7 -11
- package/dist/lexicons/types/com/atproto/server/refreshSession.js +1 -2
- package/dist/lexicons/types/com/atproto/server/requestAccountDelete.js +1 -2
- package/dist/lexicons/types/com/atproto/server/requestEmailConfirmation.js +1 -2
- package/dist/lexicons/types/com/atproto/server/requestEmailUpdate.js +1 -2
- package/dist/lexicons/types/com/atproto/server/requestPasswordReset.js +1 -2
- package/dist/lexicons/types/com/atproto/server/reserveSigningKey.js +1 -2
- package/dist/lexicons/types/com/atproto/server/resetPassword.js +1 -2
- package/dist/lexicons/types/com/atproto/server/revokeAppPassword.js +1 -2
- package/dist/lexicons/types/com/atproto/server/updateEmail.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/getBlob.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/getBlocks.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/getCheckout.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/getHead.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/getLatestCommit.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/getRecord.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/getRepo.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/getRepoStatus.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/listBlobs.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/listRepos.js +7 -11
- package/dist/lexicons/types/com/atproto/sync/listReposByCollection.js +7 -11
- package/dist/lexicons/types/com/atproto/sync/notifyOfUpdate.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/requestCrawl.js +1 -2
- package/dist/lexicons/types/com/atproto/sync/subscribeRepos.js +32 -46
- package/dist/lexicons/types/com/atproto/temp/addReservedHandle.js +1 -2
- package/dist/lexicons/types/com/atproto/temp/checkSignupQueue.js +1 -2
- package/dist/lexicons/types/com/atproto/temp/fetchLabels.js +1 -2
- package/dist/lexicons/types/com/atproto/temp/requestPhoneVerification.js +1 -2
- package/dist/lexicons/types/com/clioplaylists/alpha/actor/profile.js +7 -11
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/defs.js +12 -18
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/getSongs.js +1 -2
- package/dist/lexicons/types/com/clioplaylists/alpha/feed/playlistIdea.js +17 -25
- package/dist/lexicons/util.js +2 -6
- package/dist/logger.js +10 -16
- package/dist/rpc/clio_connect.js +30 -33
- package/dist/rpc/clio_pb.js +402 -956
- package/dist/start.js +9 -1
- package/dist/util/retry.js +7 -10
- package/dist/util/uris.js +3 -6
- package/dist/util.js +17 -60
- package/package.json +4 -4
package/dist/client.js
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
exports.createBaseClient = void 0;
|
|
7
|
-
const connect_1 = require("@connectrpc/connect");
|
|
8
|
-
const connect_node_1 = require("@connectrpc/connect-node");
|
|
9
|
-
const node_assert_1 = __importDefault(require("node:assert"));
|
|
10
|
-
const clio_connect_1 = require("./rpc/clio_connect");
|
|
11
|
-
const createBaseClient = (baseUrl, opts) => {
|
|
1
|
+
import { createClient } from '@connectrpc/connect';
|
|
2
|
+
import { createGrpcTransport } from '@connectrpc/connect-node';
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
import { ClioService } from './rpc/clio_connect';
|
|
5
|
+
export const createBaseClient = (baseUrl, opts) => {
|
|
12
6
|
const { httpVersion = '2', rejectUnauthorized = true } = opts;
|
|
13
|
-
const transport =
|
|
7
|
+
const transport = createGrpcTransport({
|
|
14
8
|
baseUrl,
|
|
15
9
|
acceptCompression: [],
|
|
16
10
|
httpVersion,
|
|
17
11
|
nodeOptions: { rejectUnauthorized },
|
|
18
12
|
});
|
|
19
|
-
(
|
|
20
|
-
return
|
|
13
|
+
assert(validateUrl(baseUrl));
|
|
14
|
+
return createClient(ClioService, transport);
|
|
21
15
|
};
|
|
22
|
-
exports.createBaseClient = createBaseClient;
|
|
23
16
|
const validateUrl = (urlStr) => {
|
|
24
17
|
let url;
|
|
25
18
|
try {
|
package/dist/config.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export interface ServerConfigValues {
|
|
|
5
5
|
serverDid: string;
|
|
6
6
|
didPlcUrl: string;
|
|
7
7
|
handleResolverNameservers?: string[];
|
|
8
|
+
dataplaneUrls: string[];
|
|
8
9
|
}
|
|
9
10
|
export declare class ServerConfig {
|
|
10
11
|
private cfg;
|
|
@@ -18,4 +19,5 @@ export declare class ServerConfig {
|
|
|
18
19
|
get localUrl(): string;
|
|
19
20
|
get serverDid(): string;
|
|
20
21
|
get didPlcUrl(): string;
|
|
22
|
+
get dataplaneUrls(): string[];
|
|
21
23
|
}
|
package/dist/config.js
CHANGED
|
@@ -1,30 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ServerConfig = void 0;
|
|
7
|
-
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
|
-
class ServerConfig {
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
export class ServerConfig {
|
|
3
|
+
cfg;
|
|
4
|
+
assignedPort;
|
|
9
5
|
constructor(cfg) {
|
|
10
|
-
|
|
11
|
-
enumerable: true,
|
|
12
|
-
configurable: true,
|
|
13
|
-
writable: true,
|
|
14
|
-
value: cfg
|
|
15
|
-
});
|
|
16
|
-
Object.defineProperty(this, "assignedPort", {
|
|
17
|
-
enumerable: true,
|
|
18
|
-
configurable: true,
|
|
19
|
-
writable: true,
|
|
20
|
-
value: void 0
|
|
21
|
-
});
|
|
6
|
+
this.cfg = cfg;
|
|
22
7
|
}
|
|
23
8
|
static readEnv(overrides) {
|
|
24
9
|
const version = overrides?.version || process.env.CLIO_VERSION || undefined;
|
|
25
10
|
const debugMode = overrides?.debugMode || process.env.NODE_ENV !== 'production';
|
|
26
11
|
const serverDid = overrides?.serverDid || process.env.CLIO_SERVER_DID || 'did:example:test';
|
|
27
12
|
const didPlcUrl = overrides?.didPlcUrl || process.env.DID_PLC_URL || 'http://localhost:2582';
|
|
13
|
+
const dataplaneUrls = overrides?.dataplaneUrls ?? envList(process.env.CLIO_DATAPLANE_URLS);
|
|
28
14
|
// const handleResolverNameservers = process.env.BSKY_HANDLE_RESOLVER_NAMESERVERS
|
|
29
15
|
// ? process.env.BSKY_HANDLE_RESOLVER_NAMESERVERS.split(',')
|
|
30
16
|
// : []
|
|
@@ -36,10 +22,11 @@ class ServerConfig {
|
|
|
36
22
|
port,
|
|
37
23
|
serverDid,
|
|
38
24
|
didPlcUrl,
|
|
25
|
+
dataplaneUrls,
|
|
39
26
|
});
|
|
40
27
|
}
|
|
41
28
|
assignPort(port) {
|
|
42
|
-
(
|
|
29
|
+
assert(!this.cfg.port || this.cfg.port === port, 'Conflicting port in config');
|
|
43
30
|
this.assignedPort = port;
|
|
44
31
|
}
|
|
45
32
|
get version() {
|
|
@@ -52,7 +39,7 @@ class ServerConfig {
|
|
|
52
39
|
return this.assignedPort || this.cfg.port;
|
|
53
40
|
}
|
|
54
41
|
get localUrl() {
|
|
55
|
-
(
|
|
42
|
+
assert(this.port, 'No port assigned');
|
|
56
43
|
return `http://localhost:${this.port}`;
|
|
57
44
|
}
|
|
58
45
|
get serverDid() {
|
|
@@ -61,5 +48,12 @@ class ServerConfig {
|
|
|
61
48
|
get didPlcUrl() {
|
|
62
49
|
return this.cfg.didPlcUrl;
|
|
63
50
|
}
|
|
51
|
+
get dataplaneUrls() {
|
|
52
|
+
return this.cfg.dataplaneUrls;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function envList(str) {
|
|
56
|
+
if (str === undefined || str.length === 0)
|
|
57
|
+
return [];
|
|
58
|
+
return str.split(',');
|
|
64
59
|
}
|
|
65
|
-
exports.ServerConfig = ServerConfig;
|
package/dist/context.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Keypair } from '@atproto/crypto';
|
|
1
2
|
import { DataPlaneClient } from './client';
|
|
2
3
|
import { ServerConfig } from './config';
|
|
3
4
|
export default class AppContext {
|
|
@@ -5,7 +6,9 @@ export default class AppContext {
|
|
|
5
6
|
constructor(opts: {
|
|
6
7
|
cfg: ServerConfig;
|
|
7
8
|
dataplane: DataPlaneClient;
|
|
9
|
+
signingKey: Keypair;
|
|
8
10
|
});
|
|
9
11
|
get cfg(): ServerConfig;
|
|
10
12
|
get dataplane(): DataPlaneClient;
|
|
13
|
+
get signingKey(): Keypair;
|
|
11
14
|
}
|
package/dist/context.js
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
class AppContext {
|
|
1
|
+
export default class AppContext {
|
|
2
|
+
opts;
|
|
4
3
|
constructor(opts) {
|
|
5
|
-
|
|
6
|
-
enumerable: true,
|
|
7
|
-
configurable: true,
|
|
8
|
-
writable: true,
|
|
9
|
-
value: opts
|
|
10
|
-
});
|
|
4
|
+
this.opts = opts;
|
|
11
5
|
}
|
|
12
6
|
get cfg() {
|
|
13
7
|
return this.opts.cfg;
|
|
@@ -15,5 +9,7 @@ class AppContext {
|
|
|
15
9
|
get dataplane() {
|
|
16
10
|
return this.opts.dataplane;
|
|
17
11
|
}
|
|
12
|
+
get signingKey() {
|
|
13
|
+
return this.opts.signingKey;
|
|
14
|
+
}
|
|
18
15
|
}
|
|
19
|
-
exports.default = AppContext;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for a reactive list of hosts, i.e. for use with the dataplane client.
|
|
3
|
+
*/
|
|
4
|
+
export interface HostList {
|
|
5
|
+
get: () => Iterable<string>;
|
|
6
|
+
onUpdate(handler: HostListHandler): void;
|
|
7
|
+
}
|
|
8
|
+
type HostListHandler = (hosts: Iterable<string>) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Maintains a reactive HostList based on a simple setter.
|
|
11
|
+
*/
|
|
12
|
+
export declare class BasicHostList implements HostList {
|
|
13
|
+
private hosts;
|
|
14
|
+
private handlers;
|
|
15
|
+
constructor(hosts: Iterable<string>);
|
|
16
|
+
get(): Iterable<string>;
|
|
17
|
+
set(hosts: Iterable<string>): void;
|
|
18
|
+
private update;
|
|
19
|
+
onUpdate(handler: HostListHandler): void;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maintains a reactive HostList based on a simple setter.
|
|
3
|
+
*/
|
|
4
|
+
export class BasicHostList {
|
|
5
|
+
hosts;
|
|
6
|
+
handlers = [];
|
|
7
|
+
constructor(hosts) {
|
|
8
|
+
this.hosts = hosts;
|
|
9
|
+
}
|
|
10
|
+
get() {
|
|
11
|
+
return this.hosts;
|
|
12
|
+
}
|
|
13
|
+
set(hosts) {
|
|
14
|
+
this.hosts = hosts;
|
|
15
|
+
this.update();
|
|
16
|
+
}
|
|
17
|
+
update() {
|
|
18
|
+
for (const handler of this.handlers) {
|
|
19
|
+
handler(this.hosts);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
onUpdate(handler) {
|
|
23
|
+
this.handlers.push(handler);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Client, Code, ConnectError } from '@connectrpc/connect';
|
|
2
|
+
import { ClioService } from '../../rpc/clio_connect';
|
|
3
|
+
import { HostList } from './hosts';
|
|
4
|
+
export type DataPlaneClient = Client<typeof ClioService>;
|
|
5
|
+
type HttpVersion = '1.1' | '2';
|
|
6
|
+
export declare const createDataPlaneClient: (hostList: HostList, opts: {
|
|
7
|
+
httpVersion?: HttpVersion;
|
|
8
|
+
rejectUnauthorized?: boolean;
|
|
9
|
+
}) => DataPlaneClient;
|
|
10
|
+
export { Code };
|
|
11
|
+
export declare const isDataplaneError: (err: unknown, code?: Code) => err is ConnectError;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Code, ConnectError, createClient, makeAnyClient, } from '@connectrpc/connect';
|
|
2
|
+
import { createGrpcTransport } from '@connectrpc/connect-node';
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
import { randomInt } from 'node:crypto';
|
|
5
|
+
import { ClioService } from '../../rpc/clio_connect';
|
|
6
|
+
const MAX_RETRIES = 3;
|
|
7
|
+
export const createDataPlaneClient = (hostList, opts) => {
|
|
8
|
+
const clients = new DataPlaneClients(hostList, opts);
|
|
9
|
+
return makeAnyClient(ClioService, (method) => {
|
|
10
|
+
return async (...args) => {
|
|
11
|
+
let tries = 0;
|
|
12
|
+
let error;
|
|
13
|
+
let remainingClients = clients.get();
|
|
14
|
+
while (tries < MAX_RETRIES) {
|
|
15
|
+
const client = randomElement(remainingClients);
|
|
16
|
+
assert(client, 'no clients available');
|
|
17
|
+
try {
|
|
18
|
+
return await client[method.localName](...args);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err instanceof ConnectError &&
|
|
22
|
+
(err.code === Code.Unavailable || err.code === Code.Aborted)) {
|
|
23
|
+
tries++;
|
|
24
|
+
error = err;
|
|
25
|
+
remainingClients = getRemainingClients(remainingClients, client);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
throw err;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
assert(error);
|
|
33
|
+
throw error;
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
export { Code };
|
|
38
|
+
/**
|
|
39
|
+
* Uses a reactive HostList in order to maintain a pool of DataPlaneClients.
|
|
40
|
+
* Each DataPlaneClient is cached per host so that it maintains connections
|
|
41
|
+
* and other internal state when the underlying HostList is updated.
|
|
42
|
+
*/
|
|
43
|
+
class DataPlaneClients {
|
|
44
|
+
hostList;
|
|
45
|
+
clientOpts;
|
|
46
|
+
clients = [];
|
|
47
|
+
clientsByHost = new Map();
|
|
48
|
+
constructor(hostList, clientOpts) {
|
|
49
|
+
this.hostList = hostList;
|
|
50
|
+
this.clientOpts = clientOpts;
|
|
51
|
+
this.refresh();
|
|
52
|
+
this.hostList.onUpdate(() => this.refresh());
|
|
53
|
+
}
|
|
54
|
+
get() {
|
|
55
|
+
return this.clients;
|
|
56
|
+
}
|
|
57
|
+
refresh() {
|
|
58
|
+
this.clients = [];
|
|
59
|
+
for (const host of this.hostList.get()) {
|
|
60
|
+
let client = this.clientsByHost.get(host);
|
|
61
|
+
if (!client) {
|
|
62
|
+
client = this.createClient(host);
|
|
63
|
+
this.clientsByHost.set(host, client);
|
|
64
|
+
}
|
|
65
|
+
this.clients.push(client);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
createClient(host) {
|
|
69
|
+
return createBaseClient(host, this.clientOpts);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export const isDataplaneError = (err, code) => {
|
|
73
|
+
if (err instanceof ConnectError) {
|
|
74
|
+
return !code || err.code === code;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
};
|
|
78
|
+
const createBaseClient = (baseUrl, opts) => {
|
|
79
|
+
const { httpVersion = '2', rejectUnauthorized = true } = opts;
|
|
80
|
+
const transport = createGrpcTransport({
|
|
81
|
+
baseUrl,
|
|
82
|
+
httpVersion,
|
|
83
|
+
acceptCompression: [],
|
|
84
|
+
nodeOptions: { rejectUnauthorized },
|
|
85
|
+
});
|
|
86
|
+
return createClient(ClioService, transport);
|
|
87
|
+
};
|
|
88
|
+
const getRemainingClients = (clients, lastClient) => {
|
|
89
|
+
if (clients.length < 2)
|
|
90
|
+
return clients; // no clients to choose from
|
|
91
|
+
return clients.filter((c) => c !== lastClient);
|
|
92
|
+
};
|
|
93
|
+
const randomElement = (arr) => {
|
|
94
|
+
if (arr.length === 0)
|
|
95
|
+
return;
|
|
96
|
+
return arr[randomInt(arr.length)];
|
|
97
|
+
};
|
package/dist/dataplane/client.js
CHANGED
|
@@ -1,68 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.getKeyAsDidKey = exports.getServiceEndpoint = exports.unpackIdentityKeys = exports.unpackIdentityServices = exports.isDataplaneError = exports.Code = exports.createDataPlaneClient = void 0;
|
|
40
|
-
const identity_1 = require("@atproto/identity");
|
|
41
|
-
const connect_1 = require("@connectrpc/connect");
|
|
42
|
-
Object.defineProperty(exports, "Code", { enumerable: true, get: function () { return connect_1.Code; } });
|
|
43
|
-
const connect_node_1 = require("@connectrpc/connect-node");
|
|
44
|
-
const node_assert_1 = __importDefault(require("node:assert"));
|
|
45
|
-
const node_crypto_1 = require("node:crypto");
|
|
46
|
-
const ui8 = __importStar(require("uint8arrays"));
|
|
47
|
-
const clio_connect_1 = require("../rpc/clio_connect");
|
|
1
|
+
import { getDidKeyFromMultibase } from '@atproto/identity';
|
|
2
|
+
import { Code, ConnectError, createClient, makeAnyClient, } from '@connectrpc/connect';
|
|
3
|
+
import { createGrpcTransport } from '@connectrpc/connect-node';
|
|
4
|
+
import assert from 'node:assert';
|
|
5
|
+
import { randomInt } from 'node:crypto';
|
|
6
|
+
import * as ui8 from 'uint8arrays';
|
|
7
|
+
import { ClioService } from '../rpc/clio_connect';
|
|
48
8
|
const MAX_RETRIES = 3;
|
|
49
|
-
const createDataPlaneClient = (baseUrls, opts) => {
|
|
9
|
+
export const createDataPlaneClient = (baseUrls, opts) => {
|
|
50
10
|
const clients = baseUrls.map((baseUrl) => createBaseClient(baseUrl, opts));
|
|
51
|
-
(
|
|
52
|
-
return
|
|
11
|
+
assert(clients.length > 0, 'no clients available');
|
|
12
|
+
return makeAnyClient(ClioService, (method) => {
|
|
53
13
|
return async (...args) => {
|
|
54
14
|
let tries = 0;
|
|
55
15
|
let error;
|
|
56
16
|
let remainingClients = clients;
|
|
57
17
|
while (tries < MAX_RETRIES) {
|
|
58
18
|
const client = randomElement(remainingClients);
|
|
59
|
-
(
|
|
19
|
+
assert(client, 'no clients available');
|
|
60
20
|
try {
|
|
61
21
|
return await client.lib[method.localName](...args);
|
|
62
22
|
}
|
|
63
23
|
catch (err) {
|
|
64
|
-
if (err instanceof
|
|
65
|
-
(err.code ===
|
|
24
|
+
if (err instanceof ConnectError &&
|
|
25
|
+
(err.code === Code.Unavailable || err.code === Code.Aborted)) {
|
|
66
26
|
tries++;
|
|
67
27
|
error = err;
|
|
68
28
|
remainingClients = getRemainingClients(remainingClients, client);
|
|
@@ -72,29 +32,28 @@ const createDataPlaneClient = (baseUrls, opts) => {
|
|
|
72
32
|
}
|
|
73
33
|
}
|
|
74
34
|
}
|
|
75
|
-
(
|
|
35
|
+
assert(error);
|
|
76
36
|
throw error;
|
|
77
37
|
};
|
|
78
38
|
});
|
|
79
39
|
};
|
|
80
|
-
|
|
81
|
-
const isDataplaneError = (err, code) => {
|
|
82
|
-
if (err instanceof
|
|
40
|
+
export { Code };
|
|
41
|
+
export const isDataplaneError = (err, code) => {
|
|
42
|
+
if (err instanceof ConnectError) {
|
|
83
43
|
return !code || err.code === code;
|
|
84
44
|
}
|
|
85
45
|
return false;
|
|
86
46
|
};
|
|
87
|
-
exports.isDataplaneError = isDataplaneError;
|
|
88
47
|
const createBaseClient = (baseUrl, opts) => {
|
|
89
48
|
const { httpVersion = '2', rejectUnauthorized = true } = opts;
|
|
90
|
-
const transport =
|
|
49
|
+
const transport = createGrpcTransport({
|
|
91
50
|
baseUrl,
|
|
92
51
|
httpVersion,
|
|
93
52
|
acceptCompression: [],
|
|
94
53
|
nodeOptions: { rejectUnauthorized },
|
|
95
54
|
});
|
|
96
55
|
return {
|
|
97
|
-
lib:
|
|
56
|
+
lib: createClient(ClioService, transport),
|
|
98
57
|
url: new URL(baseUrl),
|
|
99
58
|
};
|
|
100
59
|
};
|
|
@@ -113,38 +72,34 @@ const getRemainingClients = (clients, lastClient) => {
|
|
|
113
72
|
const randomElement = (arr) => {
|
|
114
73
|
if (arr.length === 0)
|
|
115
74
|
return;
|
|
116
|
-
return arr[
|
|
75
|
+
return arr[randomInt(arr.length)];
|
|
117
76
|
};
|
|
118
|
-
const unpackIdentityServices = (servicesBytes) => {
|
|
77
|
+
export const unpackIdentityServices = (servicesBytes) => {
|
|
119
78
|
const servicesStr = ui8.toString(servicesBytes, 'utf8');
|
|
120
79
|
if (!servicesStr)
|
|
121
80
|
return {};
|
|
122
81
|
return JSON.parse(servicesStr);
|
|
123
82
|
};
|
|
124
|
-
|
|
125
|
-
const unpackIdentityKeys = (keysBytes) => {
|
|
83
|
+
export const unpackIdentityKeys = (keysBytes) => {
|
|
126
84
|
const keysStr = ui8.toString(keysBytes, 'utf8');
|
|
127
85
|
if (!keysStr)
|
|
128
86
|
return {};
|
|
129
87
|
return JSON.parse(keysStr);
|
|
130
88
|
};
|
|
131
|
-
|
|
132
|
-
const getServiceEndpoint = (services, opts) => {
|
|
89
|
+
export const getServiceEndpoint = (services, opts) => {
|
|
133
90
|
const endpoint = services[opts.id] &&
|
|
134
91
|
services[opts.id].Type === opts.type &&
|
|
135
92
|
validateUrl(services[opts.id].URL);
|
|
136
93
|
return endpoint || undefined;
|
|
137
94
|
};
|
|
138
|
-
|
|
139
|
-
const getKeyAsDidKey = (keys, opts) => {
|
|
95
|
+
export const getKeyAsDidKey = (keys, opts) => {
|
|
140
96
|
const key = keys[opts.id] &&
|
|
141
|
-
|
|
97
|
+
getDidKeyFromMultibase({
|
|
142
98
|
type: keys[opts.id].Type,
|
|
143
99
|
publicKeyMultibase: keys[opts.id].PublicKeyMultibase,
|
|
144
100
|
});
|
|
145
101
|
return key || undefined;
|
|
146
102
|
};
|
|
147
|
-
exports.getKeyAsDidKey = getKeyAsDidKey;
|
|
148
103
|
const validateUrl = (urlStr) => {
|
|
149
104
|
let url;
|
|
150
105
|
try {
|
package/dist/dataplane/index.js
CHANGED
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./client"), exports);
|
|
18
|
-
__exportStar(require("./server"), exports);
|
|
1
|
+
export * from './client';
|
|
2
|
+
export * from './server';
|
|
@@ -1,32 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.BackgroundQueue = void 0;
|
|
7
|
-
const p_queue_1 = __importDefault(require("p-queue"));
|
|
8
|
-
const logger_1 = require("../../logger");
|
|
1
|
+
import PQueue from 'p-queue';
|
|
2
|
+
import { dbLogger } from '../../logger';
|
|
9
3
|
// A simple queue for in-process, out-of-band/backgrounded work
|
|
10
|
-
class BackgroundQueue {
|
|
4
|
+
export class BackgroundQueue {
|
|
5
|
+
db;
|
|
6
|
+
queue = new PQueue();
|
|
7
|
+
destroyed = false;
|
|
11
8
|
constructor(db) {
|
|
12
|
-
|
|
13
|
-
enumerable: true,
|
|
14
|
-
configurable: true,
|
|
15
|
-
writable: true,
|
|
16
|
-
value: db
|
|
17
|
-
});
|
|
18
|
-
Object.defineProperty(this, "queue", {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
configurable: true,
|
|
21
|
-
writable: true,
|
|
22
|
-
value: new p_queue_1.default()
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(this, "destroyed", {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
configurable: true,
|
|
27
|
-
writable: true,
|
|
28
|
-
value: false
|
|
29
|
-
});
|
|
9
|
+
this.db = db;
|
|
30
10
|
}
|
|
31
11
|
add(task) {
|
|
32
12
|
if (this.destroyed) {
|
|
@@ -35,7 +15,7 @@ class BackgroundQueue {
|
|
|
35
15
|
this.queue
|
|
36
16
|
.add(() => task(this.db))
|
|
37
17
|
.catch((err) => {
|
|
38
|
-
|
|
18
|
+
dbLogger.error(err, 'background queue task failed');
|
|
39
19
|
});
|
|
40
20
|
}
|
|
41
21
|
async processAll() {
|
|
@@ -48,4 +28,3 @@ class BackgroundQueue {
|
|
|
48
28
|
await this.queue.onIdle();
|
|
49
29
|
}
|
|
50
30
|
}
|
|
51
|
-
exports.BackgroundQueue = BackgroundQueue;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|