@clioplaylists/clio 0.1.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.
Files changed (170) hide show
  1. package/dist/.env +7 -0
  2. package/dist/api/com/clioplaylists/alpha/actor/getProfile.js +37 -0
  3. package/dist/api/com/clioplaylists/alpha/feed/getSongs.js +37 -0
  4. package/dist/api/health.js +32 -0
  5. package/dist/api/index.js +43 -0
  6. package/dist/api/util.js +17 -0
  7. package/dist/auth-verifier.js +473 -0
  8. package/dist/client.js +40 -0
  9. package/dist/config.js +65 -0
  10. package/dist/context.js +19 -0
  11. package/dist/dataplane/bsync/index.js +150 -0
  12. package/dist/dataplane/client.js +165 -0
  13. package/dist/dataplane/index.js +18 -0
  14. package/dist/dataplane/server/background.js +51 -0
  15. package/dist/dataplane/server/db/database-schema.js +2 -0
  16. package/dist/dataplane/server/db/db.js +228 -0
  17. package/dist/dataplane/server/db/index.js +17 -0
  18. package/dist/dataplane/server/db/migrations/20230309T045948368Z-init.js +117 -0
  19. package/dist/dataplane/server/db/migrations/20230420T211446071Z-did-cache.js +15 -0
  20. package/dist/dataplane/server/db/migrations/index.js +41 -0
  21. package/dist/dataplane/server/db/migrations/provider.js +31 -0
  22. package/dist/dataplane/server/db/pagination.js +144 -0
  23. package/dist/dataplane/server/db/tables/actor-sync.js +4 -0
  24. package/dist/dataplane/server/db/tables/actor.js +4 -0
  25. package/dist/dataplane/server/db/tables/artist-list-item.js +4 -0
  26. package/dist/dataplane/server/db/tables/artist.js +4 -0
  27. package/dist/dataplane/server/db/tables/playlist-idea.js +4 -0
  28. package/dist/dataplane/server/db/tables/playlist-item.js +4 -0
  29. package/dist/dataplane/server/db/tables/playlist.js +4 -0
  30. package/dist/dataplane/server/db/tables/profile.js +4 -0
  31. package/dist/dataplane/server/db/tables/record.js +4 -0
  32. package/dist/dataplane/server/db/tables/song.js +4 -0
  33. package/dist/dataplane/server/db/types.js +2 -0
  34. package/dist/dataplane/server/db/util.js +48 -0
  35. package/dist/dataplane/server/index.js +52 -0
  36. package/dist/dataplane/server/indexing/index.js +321 -0
  37. package/dist/dataplane/server/indexing/plugins/playlist-idea.js +163 -0
  38. package/dist/dataplane/server/indexing/plugins/profile.js +81 -0
  39. package/dist/dataplane/server/indexing/processor.js +90 -0
  40. package/dist/dataplane/server/routes/blocks.js +95 -0
  41. package/dist/dataplane/server/routes/feed-gens.js +56 -0
  42. package/dist/dataplane/server/routes/feeds.js +128 -0
  43. package/dist/dataplane/server/routes/follows.js +122 -0
  44. package/dist/dataplane/server/routes/identity.js +56 -0
  45. package/dist/dataplane/server/routes/index.js +19 -0
  46. package/dist/dataplane/server/routes/interactions.js +111 -0
  47. package/dist/dataplane/server/routes/labels.js +73 -0
  48. package/dist/dataplane/server/routes/likes.js +76 -0
  49. package/dist/dataplane/server/routes/lists.js +77 -0
  50. package/dist/dataplane/server/routes/moderation.js +92 -0
  51. package/dist/dataplane/server/routes/mutes.js +166 -0
  52. package/dist/dataplane/server/routes/notifs.js +137 -0
  53. package/dist/dataplane/server/routes/posts.js +19 -0
  54. package/dist/dataplane/server/routes/profile.js +61 -0
  55. package/dist/dataplane/server/routes/quotes.js +26 -0
  56. package/dist/dataplane/server/routes/records.js +88 -0
  57. package/dist/dataplane/server/routes/relationships.js +157 -0
  58. package/dist/dataplane/server/routes/reposts.js +59 -0
  59. package/dist/dataplane/server/routes/search.js +70 -0
  60. package/dist/dataplane/server/routes/starter-packs.js +24 -0
  61. package/dist/dataplane/server/routes/suggestions.js +134 -0
  62. package/dist/dataplane/server/routes/sync.js +14 -0
  63. package/dist/dataplane/server/routes/threads.js +31 -0
  64. package/dist/dataplane/server/subscription.js +114 -0
  65. package/dist/dataplane/server/util.js +117 -0
  66. package/dist/error.js +14 -0
  67. package/dist/index.js +115 -0
  68. package/dist/lexicons/index.js +638 -0
  69. package/dist/lexicons/lexicons.js +4551 -0
  70. package/dist/lexicons/types/com/atproto/admin/defs.js +54 -0
  71. package/dist/lexicons/types/com/atproto/admin/deleteAccount.js +2 -0
  72. package/dist/lexicons/types/com/atproto/admin/disableAccountInvites.js +2 -0
  73. package/dist/lexicons/types/com/atproto/admin/disableInviteCodes.js +2 -0
  74. package/dist/lexicons/types/com/atproto/admin/enableAccountInvites.js +2 -0
  75. package/dist/lexicons/types/com/atproto/admin/getAccountInfo.js +2 -0
  76. package/dist/lexicons/types/com/atproto/admin/getAccountInfos.js +2 -0
  77. package/dist/lexicons/types/com/atproto/admin/getInviteCodes.js +2 -0
  78. package/dist/lexicons/types/com/atproto/admin/getSubjectStatus.js +2 -0
  79. package/dist/lexicons/types/com/atproto/admin/searchAccounts.js +2 -0
  80. package/dist/lexicons/types/com/atproto/admin/sendEmail.js +2 -0
  81. package/dist/lexicons/types/com/atproto/admin/updateAccountEmail.js +2 -0
  82. package/dist/lexicons/types/com/atproto/admin/updateAccountHandle.js +2 -0
  83. package/dist/lexicons/types/com/atproto/admin/updateAccountPassword.js +2 -0
  84. package/dist/lexicons/types/com/atproto/admin/updateSubjectStatus.js +2 -0
  85. package/dist/lexicons/types/com/atproto/identity/defs.js +14 -0
  86. package/dist/lexicons/types/com/atproto/identity/getRecommendedDidCredentials.js +2 -0
  87. package/dist/lexicons/types/com/atproto/identity/refreshIdentity.js +2 -0
  88. package/dist/lexicons/types/com/atproto/identity/requestPlcOperationSignature.js +2 -0
  89. package/dist/lexicons/types/com/atproto/identity/resolveDid.js +2 -0
  90. package/dist/lexicons/types/com/atproto/identity/resolveHandle.js +2 -0
  91. package/dist/lexicons/types/com/atproto/identity/resolveIdentity.js +2 -0
  92. package/dist/lexicons/types/com/atproto/identity/signPlcOperation.js +2 -0
  93. package/dist/lexicons/types/com/atproto/identity/submitPlcOperation.js +2 -0
  94. package/dist/lexicons/types/com/atproto/identity/updateHandle.js +2 -0
  95. package/dist/lexicons/types/com/atproto/label/defs.js +54 -0
  96. package/dist/lexicons/types/com/atproto/label/queryLabels.js +2 -0
  97. package/dist/lexicons/types/com/atproto/label/subscribeLabels.js +24 -0
  98. package/dist/lexicons/types/com/atproto/lexicon/schema.js +15 -0
  99. package/dist/lexicons/types/com/atproto/moderation/createReport.js +2 -0
  100. package/dist/lexicons/types/com/atproto/moderation/defs.js +20 -0
  101. package/dist/lexicons/types/com/atproto/repo/applyWrites.js +64 -0
  102. package/dist/lexicons/types/com/atproto/repo/createRecord.js +2 -0
  103. package/dist/lexicons/types/com/atproto/repo/defs.js +14 -0
  104. package/dist/lexicons/types/com/atproto/repo/deleteRecord.js +2 -0
  105. package/dist/lexicons/types/com/atproto/repo/describeRepo.js +2 -0
  106. package/dist/lexicons/types/com/atproto/repo/getRecord.js +2 -0
  107. package/dist/lexicons/types/com/atproto/repo/importRepo.js +2 -0
  108. package/dist/lexicons/types/com/atproto/repo/listMissingBlobs.js +14 -0
  109. package/dist/lexicons/types/com/atproto/repo/listRecords.js +14 -0
  110. package/dist/lexicons/types/com/atproto/repo/putRecord.js +2 -0
  111. package/dist/lexicons/types/com/atproto/repo/strongRef.js +15 -0
  112. package/dist/lexicons/types/com/atproto/repo/uploadBlob.js +2 -0
  113. package/dist/lexicons/types/com/atproto/server/activateAccount.js +2 -0
  114. package/dist/lexicons/types/com/atproto/server/checkAccountStatus.js +2 -0
  115. package/dist/lexicons/types/com/atproto/server/confirmEmail.js +2 -0
  116. package/dist/lexicons/types/com/atproto/server/createAccount.js +2 -0
  117. package/dist/lexicons/types/com/atproto/server/createAppPassword.js +14 -0
  118. package/dist/lexicons/types/com/atproto/server/createInviteCode.js +2 -0
  119. package/dist/lexicons/types/com/atproto/server/createInviteCodes.js +14 -0
  120. package/dist/lexicons/types/com/atproto/server/createSession.js +2 -0
  121. package/dist/lexicons/types/com/atproto/server/deactivateAccount.js +2 -0
  122. package/dist/lexicons/types/com/atproto/server/defs.js +24 -0
  123. package/dist/lexicons/types/com/atproto/server/deleteAccount.js +2 -0
  124. package/dist/lexicons/types/com/atproto/server/deleteSession.js +2 -0
  125. package/dist/lexicons/types/com/atproto/server/describeServer.js +24 -0
  126. package/dist/lexicons/types/com/atproto/server/getAccountInviteCodes.js +2 -0
  127. package/dist/lexicons/types/com/atproto/server/getServiceAuth.js +2 -0
  128. package/dist/lexicons/types/com/atproto/server/getSession.js +2 -0
  129. package/dist/lexicons/types/com/atproto/server/listAppPasswords.js +14 -0
  130. package/dist/lexicons/types/com/atproto/server/refreshSession.js +2 -0
  131. package/dist/lexicons/types/com/atproto/server/requestAccountDelete.js +2 -0
  132. package/dist/lexicons/types/com/atproto/server/requestEmailConfirmation.js +2 -0
  133. package/dist/lexicons/types/com/atproto/server/requestEmailUpdate.js +2 -0
  134. package/dist/lexicons/types/com/atproto/server/requestPasswordReset.js +2 -0
  135. package/dist/lexicons/types/com/atproto/server/reserveSigningKey.js +2 -0
  136. package/dist/lexicons/types/com/atproto/server/resetPassword.js +2 -0
  137. package/dist/lexicons/types/com/atproto/server/revokeAppPassword.js +2 -0
  138. package/dist/lexicons/types/com/atproto/server/updateEmail.js +2 -0
  139. package/dist/lexicons/types/com/atproto/sync/getBlob.js +2 -0
  140. package/dist/lexicons/types/com/atproto/sync/getBlocks.js +2 -0
  141. package/dist/lexicons/types/com/atproto/sync/getCheckout.js +2 -0
  142. package/dist/lexicons/types/com/atproto/sync/getHead.js +2 -0
  143. package/dist/lexicons/types/com/atproto/sync/getLatestCommit.js +2 -0
  144. package/dist/lexicons/types/com/atproto/sync/getRecord.js +2 -0
  145. package/dist/lexicons/types/com/atproto/sync/getRepo.js +2 -0
  146. package/dist/lexicons/types/com/atproto/sync/getRepoStatus.js +2 -0
  147. package/dist/lexicons/types/com/atproto/sync/listBlobs.js +2 -0
  148. package/dist/lexicons/types/com/atproto/sync/listRepos.js +14 -0
  149. package/dist/lexicons/types/com/atproto/sync/listReposByCollection.js +14 -0
  150. package/dist/lexicons/types/com/atproto/sync/notifyOfUpdate.js +2 -0
  151. package/dist/lexicons/types/com/atproto/sync/requestCrawl.js +2 -0
  152. package/dist/lexicons/types/com/atproto/sync/subscribeRepos.js +64 -0
  153. package/dist/lexicons/types/com/atproto/temp/addReservedHandle.js +2 -0
  154. package/dist/lexicons/types/com/atproto/temp/checkSignupQueue.js +2 -0
  155. package/dist/lexicons/types/com/atproto/temp/fetchLabels.js +2 -0
  156. package/dist/lexicons/types/com/atproto/temp/requestPhoneVerification.js +2 -0
  157. package/dist/lexicons/types/com/clioplaylists/alpha/actor/profile.js +15 -0
  158. package/dist/lexicons/types/com/clioplaylists/alpha/feed/defs.js +24 -0
  159. package/dist/lexicons/types/com/clioplaylists/alpha/feed/getSongs.js +2 -0
  160. package/dist/lexicons/types/com/clioplaylists/alpha/feed/playlistIdea.js +35 -0
  161. package/dist/lexicons/types/com/clioplaylists/alpha/feed/song.js +25 -0
  162. package/dist/lexicons/util.js +13 -0
  163. package/dist/logger.js +26 -0
  164. package/dist/rpc/clio_connect.js +110 -0
  165. package/dist/rpc/clio_pb.js +1365 -0
  166. package/dist/start.js +13 -0
  167. package/dist/util/retry.js +16 -0
  168. package/dist/util/uris.js +7 -0
  169. package/dist/util.js +119 -0
  170. package/package.json +73 -0
package/dist/client.js ADDED
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
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) => {
12
+ const { httpVersion = '2', rejectUnauthorized = true } = opts;
13
+ const transport = (0, connect_node_1.createGrpcTransport)({
14
+ baseUrl,
15
+ acceptCompression: [],
16
+ httpVersion,
17
+ nodeOptions: { rejectUnauthorized },
18
+ });
19
+ (0, node_assert_1.default)(validateUrl(baseUrl));
20
+ return (0, connect_1.createClient)(clio_connect_1.ClioService, transport);
21
+ };
22
+ exports.createBaseClient = createBaseClient;
23
+ const validateUrl = (urlStr) => {
24
+ let url;
25
+ try {
26
+ url = new URL(urlStr);
27
+ }
28
+ catch {
29
+ return undefined;
30
+ }
31
+ if (!['http:', 'https:'].includes(url.protocol)) {
32
+ return undefined;
33
+ }
34
+ else if (!url.hostname) {
35
+ return undefined;
36
+ }
37
+ else {
38
+ return urlStr;
39
+ }
40
+ };
package/dist/config.js ADDED
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
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 {
9
+ constructor(cfg) {
10
+ Object.defineProperty(this, "cfg", {
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
+ });
22
+ }
23
+ static readEnv(overrides) {
24
+ const version = overrides?.version || process.env.CLIO_VERSION || undefined;
25
+ const debugMode = overrides?.debugMode || process.env.NODE_ENV !== 'production';
26
+ const serverDid = overrides?.serverDid || process.env.CLIO_SERVER_DID || 'did:example:test';
27
+ const didPlcUrl = overrides?.didPlcUrl || process.env.DID_PLC_URL || 'http://localhost:2582';
28
+ // const handleResolverNameservers = process.env.BSKY_HANDLE_RESOLVER_NAMESERVERS
29
+ // ? process.env.BSKY_HANDLE_RESOLVER_NAMESERVERS.split(',')
30
+ // : []
31
+ const envPort = overrides?.port || parseInt(process.env.CLIO_PORT || '', 10);
32
+ const port = isNaN(envPort) ? 2635 : envPort;
33
+ return new ServerConfig({
34
+ version,
35
+ debugMode,
36
+ port,
37
+ serverDid,
38
+ didPlcUrl,
39
+ });
40
+ }
41
+ assignPort(port) {
42
+ (0, node_assert_1.default)(!this.cfg.port || this.cfg.port === port, 'Conflicting port in config');
43
+ this.assignedPort = port;
44
+ }
45
+ get version() {
46
+ return this.cfg.version;
47
+ }
48
+ get debugMode() {
49
+ return !!this.cfg.debugMode;
50
+ }
51
+ get port() {
52
+ return this.assignedPort || this.cfg.port;
53
+ }
54
+ get localUrl() {
55
+ (0, node_assert_1.default)(this.port, 'No port assigned');
56
+ return `http://localhost:${this.port}`;
57
+ }
58
+ get serverDid() {
59
+ return this.cfg.serverDid;
60
+ }
61
+ get didPlcUrl() {
62
+ return this.cfg.didPlcUrl;
63
+ }
64
+ }
65
+ exports.ServerConfig = ServerConfig;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class AppContext {
4
+ constructor(opts) {
5
+ Object.defineProperty(this, "opts", {
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true,
9
+ value: opts
10
+ });
11
+ }
12
+ get cfg() {
13
+ return this.opts.cfg;
14
+ }
15
+ get dataplane() {
16
+ return this.opts.dataplane;
17
+ }
18
+ }
19
+ exports.default = AppContext;
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MockBsync = void 0;
7
+ const node_assert_1 = __importDefault(require("node:assert"));
8
+ const node_events_1 = __importDefault(require("node:events"));
9
+ const connect_express_1 = require("@connectrpc/connect-express");
10
+ const express_1 = __importDefault(require("express"));
11
+ const syntax_1 = require("@atproto/syntax");
12
+ const lexicons_1 = require("../../lexicon/lexicons");
13
+ const bsync_connect_1 = require("../../proto/bsync_connect");
14
+ const bsync_pb_1 = require("../../proto/bsync_pb");
15
+ class MockBsync {
16
+ constructor(server) {
17
+ Object.defineProperty(this, "server", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: server
22
+ });
23
+ }
24
+ static async create(db, port) {
25
+ const app = (0, express_1.default)();
26
+ const routes = createRoutes(db);
27
+ app.use((0, connect_express_1.expressConnectMiddleware)({ routes }));
28
+ const server = app.listen(port);
29
+ await node_events_1.default.once(server, 'listening');
30
+ return new MockBsync(server);
31
+ }
32
+ async destroy() {
33
+ return new Promise((resolve, reject) => {
34
+ this.server.close((err) => {
35
+ if (err) {
36
+ reject(err);
37
+ }
38
+ else {
39
+ resolve();
40
+ }
41
+ });
42
+ });
43
+ }
44
+ }
45
+ exports.MockBsync = MockBsync;
46
+ const createRoutes = (db) => (router) => router.service(bsync_connect_1.Service, {
47
+ async addMuteOperation(req) {
48
+ const { type, actorDid, subject } = req;
49
+ if (type === bsync_pb_1.MuteOperation_Type.ADD) {
50
+ if (subject.startsWith('did:')) {
51
+ (0, node_assert_1.default)(actorDid !== subject, 'cannot mute yourself'); // @TODO pass message through in http error
52
+ await db.db
53
+ .insertInto('mute')
54
+ .values({
55
+ mutedByDid: actorDid,
56
+ subjectDid: subject,
57
+ createdAt: new Date().toISOString(),
58
+ })
59
+ .onConflict((oc) => oc.doNothing())
60
+ .execute();
61
+ }
62
+ else {
63
+ const uri = new syntax_1.AtUri(subject);
64
+ if (uri.collection === lexicons_1.ids.AppBskyGraphList) {
65
+ await db.db
66
+ .insertInto('list_mute')
67
+ .values({
68
+ mutedByDid: actorDid,
69
+ listUri: subject,
70
+ createdAt: new Date().toISOString(),
71
+ })
72
+ .onConflict((oc) => oc.doNothing())
73
+ .execute();
74
+ }
75
+ else {
76
+ await db.db
77
+ .insertInto('thread_mute')
78
+ .values({
79
+ mutedByDid: actorDid,
80
+ rootUri: subject,
81
+ createdAt: new Date().toISOString(),
82
+ })
83
+ .onConflict((oc) => oc.doNothing())
84
+ .execute();
85
+ }
86
+ }
87
+ }
88
+ else if (type === bsync_pb_1.MuteOperation_Type.REMOVE) {
89
+ if (subject.startsWith('did:')) {
90
+ await db.db
91
+ .deleteFrom('mute')
92
+ .where('mutedByDid', '=', actorDid)
93
+ .where('subjectDid', '=', subject)
94
+ .execute();
95
+ }
96
+ else {
97
+ const uri = new syntax_1.AtUri(subject);
98
+ if (uri.collection === lexicons_1.ids.AppBskyGraphList) {
99
+ await db.db
100
+ .deleteFrom('list_mute')
101
+ .where('mutedByDid', '=', actorDid)
102
+ .where('listUri', '=', subject)
103
+ .execute();
104
+ }
105
+ else {
106
+ await db.db
107
+ .deleteFrom('thread_mute')
108
+ .where('mutedByDid', '=', actorDid)
109
+ .where('rootUri', '=', subject)
110
+ .execute();
111
+ }
112
+ }
113
+ }
114
+ else if (type === bsync_pb_1.MuteOperation_Type.CLEAR) {
115
+ await db.db
116
+ .deleteFrom('mute')
117
+ .where('mutedByDid', '=', actorDid)
118
+ .execute();
119
+ await db.db
120
+ .deleteFrom('list_mute')
121
+ .where('mutedByDid', '=', actorDid)
122
+ .execute();
123
+ }
124
+ return {};
125
+ },
126
+ async scanMuteOperations() {
127
+ throw new Error('not implemented');
128
+ },
129
+ async addNotifOperation(req) {
130
+ const { actorDid, priority } = req;
131
+ if (priority !== undefined) {
132
+ await db.db
133
+ .insertInto('actor_state')
134
+ .values({
135
+ did: actorDid,
136
+ priorityNotifs: priority,
137
+ lastSeenNotifs: new Date().toISOString(),
138
+ })
139
+ .onConflict((oc) => oc.column('did').doUpdateSet({ priorityNotifs: priority }))
140
+ .execute();
141
+ }
142
+ return {};
143
+ },
144
+ async scanNotifOperations() {
145
+ throw new Error('not implemented');
146
+ },
147
+ async ping() {
148
+ return {};
149
+ },
150
+ });
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
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 __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");
48
+ const MAX_RETRIES = 3;
49
+ const createDataPlaneClient = (baseUrls, opts) => {
50
+ const clients = baseUrls.map((baseUrl) => createBaseClient(baseUrl, opts));
51
+ (0, node_assert_1.default)(clients.length > 0, 'no clients available');
52
+ return (0, connect_1.makeAnyClient)(clio_connect_1.ClioService, (method) => {
53
+ return async (...args) => {
54
+ let tries = 0;
55
+ let error;
56
+ let remainingClients = clients;
57
+ while (tries < MAX_RETRIES) {
58
+ const client = randomElement(remainingClients);
59
+ (0, node_assert_1.default)(client, 'no clients available');
60
+ try {
61
+ return await client.lib[method.localName](...args);
62
+ }
63
+ catch (err) {
64
+ if (err instanceof connect_1.ConnectError &&
65
+ (err.code === connect_1.Code.Unavailable || err.code === connect_1.Code.Aborted)) {
66
+ tries++;
67
+ error = err;
68
+ remainingClients = getRemainingClients(remainingClients, client);
69
+ }
70
+ else {
71
+ throw err;
72
+ }
73
+ }
74
+ }
75
+ (0, node_assert_1.default)(error);
76
+ throw error;
77
+ };
78
+ });
79
+ };
80
+ exports.createDataPlaneClient = createDataPlaneClient;
81
+ const isDataplaneError = (err, code) => {
82
+ if (err instanceof connect_1.ConnectError) {
83
+ return !code || err.code === code;
84
+ }
85
+ return false;
86
+ };
87
+ exports.isDataplaneError = isDataplaneError;
88
+ const createBaseClient = (baseUrl, opts) => {
89
+ const { httpVersion = '2', rejectUnauthorized = true } = opts;
90
+ const transport = (0, connect_node_1.createGrpcTransport)({
91
+ baseUrl,
92
+ httpVersion,
93
+ acceptCompression: [],
94
+ nodeOptions: { rejectUnauthorized },
95
+ });
96
+ return {
97
+ lib: (0, connect_1.createClient)(clio_connect_1.ClioService, transport),
98
+ url: new URL(baseUrl),
99
+ };
100
+ };
101
+ const getRemainingClients = (clients, lastClient) => {
102
+ if (clients.length < 2)
103
+ return clients; // no clients to choose from
104
+ if (lastClient.url.port) {
105
+ // if the last client had a port, we attempt to exclude its whole host.
106
+ const maybeRemaining = clients.filter((c) => c.url.hostname !== lastClient.url.hostname);
107
+ if (maybeRemaining.length) {
108
+ return maybeRemaining;
109
+ }
110
+ }
111
+ return clients.filter((c) => c !== lastClient);
112
+ };
113
+ const randomElement = (arr) => {
114
+ if (arr.length === 0)
115
+ return;
116
+ return arr[(0, node_crypto_1.randomInt)(arr.length)];
117
+ };
118
+ const unpackIdentityServices = (servicesBytes) => {
119
+ const servicesStr = ui8.toString(servicesBytes, 'utf8');
120
+ if (!servicesStr)
121
+ return {};
122
+ return JSON.parse(servicesStr);
123
+ };
124
+ exports.unpackIdentityServices = unpackIdentityServices;
125
+ const unpackIdentityKeys = (keysBytes) => {
126
+ const keysStr = ui8.toString(keysBytes, 'utf8');
127
+ if (!keysStr)
128
+ return {};
129
+ return JSON.parse(keysStr);
130
+ };
131
+ exports.unpackIdentityKeys = unpackIdentityKeys;
132
+ const getServiceEndpoint = (services, opts) => {
133
+ const endpoint = services[opts.id] &&
134
+ services[opts.id].Type === opts.type &&
135
+ validateUrl(services[opts.id].URL);
136
+ return endpoint || undefined;
137
+ };
138
+ exports.getServiceEndpoint = getServiceEndpoint;
139
+ const getKeyAsDidKey = (keys, opts) => {
140
+ const key = keys[opts.id] &&
141
+ (0, identity_1.getDidKeyFromMultibase)({
142
+ type: keys[opts.id].Type,
143
+ publicKeyMultibase: keys[opts.id].PublicKeyMultibase,
144
+ });
145
+ return key || undefined;
146
+ };
147
+ exports.getKeyAsDidKey = getKeyAsDidKey;
148
+ const validateUrl = (urlStr) => {
149
+ let url;
150
+ try {
151
+ url = new URL(urlStr);
152
+ }
153
+ catch {
154
+ return undefined;
155
+ }
156
+ if (!['http:', 'https:'].includes(url.protocol)) {
157
+ return undefined;
158
+ }
159
+ else if (!url.hostname) {
160
+ return undefined;
161
+ }
162
+ else {
163
+ return urlStr;
164
+ }
165
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
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);
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
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");
9
+ // A simple queue for in-process, out-of-band/backgrounded work
10
+ class BackgroundQueue {
11
+ constructor(db) {
12
+ Object.defineProperty(this, "db", {
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
+ });
30
+ }
31
+ add(task) {
32
+ if (this.destroyed) {
33
+ return;
34
+ }
35
+ this.queue
36
+ .add(() => task(this.db))
37
+ .catch((err) => {
38
+ logger_1.dbLogger.error(err, 'background queue task failed');
39
+ });
40
+ }
41
+ async processAll() {
42
+ await this.queue.onIdle();
43
+ }
44
+ // On destroy we stop accepting new tasks, but complete all pending/in-progress tasks.
45
+ // The application calls this only once http connections have drained (tasks no longer being added).
46
+ async destroy() {
47
+ this.destroyed = true;
48
+ await this.queue.onIdle();
49
+ }
50
+ }
51
+ exports.BackgroundQueue = BackgroundQueue;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });