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