Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/conat/names.ts
5805 views
1
/*
2
Names we use with conat.
3
4
For Jetstream:
5
6
project-{project_id}-{compute_server_id}[.-service][.-{encodeBase64(path)}]
7
8
For Subjects:
9
10
project.{project-id}.{compute_server_id}[.{service}][.{path}]
11
12
*/
13
14
import generateVouchers from "@cocalc/util/vouchers";
15
import type { Location } from "./types";
16
import { encodeBase64 } from "@cocalc/conat/util";
17
18
// Service names for conat subjects
19
export const EXEC_STREAM_SERVICE = "exec-stream";
20
21
// nice alphanumeric string that can be used as conat subject, and very
22
// unlikely to randomly collide with another browser tab from this account.
23
export function randomId() {
24
return generateVouchers({ count: 1, length: 10 })[0];
25
}
26
27
// jetstream name -- we use this canonical name for the KV and the stream associated
28
// to a location in cocalc.
29
export function jsName({
30
project_id,
31
account_id,
32
hub_id,
33
}: {
34
project_id?: string;
35
account_id?: string;
36
hub_id?: string;
37
}) {
38
if (project_id) {
39
return `project-${project_id}`;
40
}
41
if (account_id) {
42
return `account-${account_id}`;
43
}
44
if (hub_id) {
45
return `hub-${hub_id}`;
46
}
47
if (process.env.COCALC_TEST_MODE) {
48
return "test";
49
} else {
50
return "public";
51
}
52
}
53
54
export function localLocationName({
55
compute_server_id,
56
browser_id,
57
path,
58
}: Location): string {
59
// !!CRITICAL WARNING!! If you ever modify this code, only do so in a way that adds a new field
60
// so that the default value of that field leaves the output of this function UNCHANGED!
61
// Otherwise, it gets used for defining the location of kv stores, and if it changes
62
// on existing inputs, then all user data across all of cocalc would just go ** POOF ** !
63
const v: string[] = [];
64
if (compute_server_id) {
65
v.push(`id=${compute_server_id}`);
66
} else if (browser_id) {
67
v.push(`id=${browser_id}`);
68
}
69
if (path) {
70
v.push(`path=${path}`);
71
}
72
return v.join(",");
73
}
74
75
/*
76
Custom inbox prefix per "user"!
77
78
So can receive response to requests, and that you can ONLY receive responses
79
to your own messages and nobody else's! This must be used in conjunction with
80
the inboxPrefix client option when connecting.
81
*/
82
export function inboxPrefix({
83
account_id,
84
project_id,
85
hub_id,
86
}: {
87
account_id?: string;
88
project_id?: string;
89
hub_id?: string;
90
}) {
91
// a project or account:
92
return `_INBOX.${jsName({ account_id, project_id, hub_id })}`;
93
}
94
95
export function streamSubject({
96
project_id,
97
account_id,
98
ephemeral,
99
}: {
100
project_id?: string;
101
account_id?: string;
102
ephemeral?: boolean;
103
}) {
104
const e = ephemeral ? "e" : "";
105
if (project_id) {
106
if (account_id) {
107
throw Error("both account_id and project_id can't be set");
108
}
109
return `project.${project_id}.${e}stream.>`;
110
}
111
if (!account_id) {
112
if (process.env.COCALC_TEST_MODE) {
113
return `test.${e}stream.>`;
114
}
115
return `public.${e}stream.>`;
116
}
117
return `account.${account_id}.${e}stream.>`;
118
}
119
120
export function projectSubject({
121
service,
122
project_id,
123
compute_server_id,
124
// path = optional name of specific path for that microservice -- replaced by its base64 encoding
125
path,
126
}: {
127
project_id: string;
128
service: string;
129
compute_server_id?: number;
130
path?: string;
131
}): string {
132
if (!project_id) {
133
throw Error("project_id must be set");
134
}
135
const segments = [
136
"project",
137
project_id,
138
compute_server_id ?? "-",
139
service ?? "-",
140
path ? encodeBase64(path) : "-",
141
];
142
return segments.join(".");
143
}
144
145
export function projectStreamName({
146
project_id,
147
// service = optional name of the microservice, e.g., 'api', 'terminal'
148
service,
149
// path = optional name of specific path for that microservice -- replaced by its base64 encoding
150
path,
151
}: {
152
project_id: string;
153
service?: string;
154
path?: string;
155
}): string {
156
if (!project_id) {
157
throw Error("project_id must be set");
158
}
159
let streamName = `project-${project_id}`;
160
if (service) {
161
streamName += "-" + service;
162
if (path) {
163
streamName += "-" + encodeBase64(path);
164
}
165
}
166
return streamName;
167
}
168
169
export function browserSubject({ account_id, sessionId, service }) {
170
if (!sessionId) {
171
throw Error("sessionId must be set");
172
}
173
if (!account_id) {
174
throw Error("account_id must be set");
175
}
176
if (!service) {
177
throw Error("service must be set");
178
}
179
return `${sessionId}.account-${account_id}.${service}`;
180
}
181
182