Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use NATS #8118

Open
wants to merge 292 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
292 commits
Select commit Hold shift + click to select a range
419067f
nats: work in progress figuring out a better type-checked way to do R…
williamstein Jan 25, 2025
aa22718
nats: starting to add db service
williamstein Jan 26, 2025
b0b36bf
nats api: a little bit of refactoring
williamstein Jan 26, 2025
5315d47
nats: foundations for changefeeds
williamstein Jan 26, 2025
08e80a8
nats: organizing startup/config
williamstein Jan 26, 2025
ea1669b
nats synctable: added support for atomic tables, which we'll use for …
williamstein Jan 26, 2025
a6a04e4
nats database changefeeds: one per query
williamstein Jan 26, 2025
4e4fda0
nats db synctable: automatically stop
williamstein Jan 26, 2025
f7fbc45
organize sync changefeed code
williamstein Jan 26, 2025
cee658c
nats synctables: got page to load and the non-project-specific tables…
williamstein Jan 26, 2025
854ec97
nats: fix collab editing
williamstein Jan 26, 2025
9a69f84
clean up use of sha1 (js version all imported from @cocalc/util); als…
williamstein Jan 27, 2025
b33ec24
more sha1 cleanup
williamstein Jan 27, 2025
7d8b198
nats api: refactoring
williamstein Jan 27, 2025
4ed5f3f
nats: refactoring hub api -- rewrite time functionality to use NATS i…
williamstein Jan 27, 2025
c37f6c8
Merge branch 'master' into nats
williamstein Jan 28, 2025
89e230c
proper pnpm-lock update
williamstein Jan 28, 2025
c78decf
Merge branch 'master' into nats
williamstein Jan 28, 2025
916987e
nats: automate installation of nats, nsc and nats-server on a given host
williamstein Jan 28, 2025
534cb21
nats: automate install/configuration/auth at least for dev mode
williamstein Jan 28, 2025
61ca262
nats: set variables to disable use of nats everywhere by default
williamstein Jan 29, 2025
ab916b8
nats: use nats for project websocket request/reply api (totally autom…
williamstein Jan 29, 2025
1c50f13
nats: automate adding permissions when connecting to project
williamstein Jan 29, 2025
d920317
nats: shorter ping times for now so nats clients start working again …
williamstein Jan 29, 2025
4463105
nats: working on implementing sockets/channels compat layer (not done)
williamstein Jan 29, 2025
040f373
nats: work in progress implementing primus style messaging on top of …
williamstein Jan 29, 2025
b852342
nats primus -- implemented basics of sparks.
williamstein Jan 29, 2025
42318f9
Merge branch 'master' into nats
williamstein Jan 29, 2025
acb4a2e
nats: get terminal fully working with "primus over nats"
williamstein Jan 29, 2025
fd8077c
nats primus: add ping interval and implement auto destroy on server side
williamstein Jan 30, 2025
445d048
nats: primus -- going to give upon this approach
williamstein Jan 30, 2025
e053a9d
nats: enable by default new project api and terminal using nats
williamstein Jan 30, 2025
c74abd9
nats: creating typescript project RPC framework
williamstein Jan 30, 2025
077c2c4
nats: start newest project api as part of starting project and add te…
williamstein Jan 30, 2025
5a610b1
nats project api: add more system functions
williamstein Jan 30, 2025
1f701f5
nats project api: add configuration
williamstein Jan 30, 2025
c2c81b2
nats project api -- implemented basically everything but sync support…
williamstein Jan 30, 2025
41d4508
nats projects: cleaning up naming (via refactor) and supporting compu…
williamstein Jan 31, 2025
c30c16a
nats: converting frontend to user new project api (and also add suppo…
williamstein Jan 31, 2025
1c4dbdc
nats: implement for kv for tracking open-files
williamstein Jan 31, 2025
2b20b90
nats OpenFiles tracker -- more work on it
williamstein Jan 31, 2025
72c4d2e
nats sync: when client browser has document open, it periodically
williamstein Jan 31, 2025
47f026c
nats open files tracker -- working on it
williamstein Jan 31, 2025
5f696a7
nats synctable-kv -- work in progress
williamstein Jan 31, 2025
3f217b9
nats synctable: writing complicated code I do NOT like. This feels l…
williamstein Jan 31, 2025
f6cf4da
nats kv synctable -- more subtle coding
williamstein Jan 31, 2025
98dc26b
nats synctable -- make non-atomic kv synctable work consistently for …
williamstein Jan 31, 2025
6e75adc
nats: plug in new synctable-kv to syncdoc for syncstrings table
williamstein Jan 31, 2025
cf77d7c
nats sync: get saving to disk to work
williamstein Jan 31, 2025
db5011e
nats: incorporate open-files service into project so it automatically…
williamstein Feb 1, 2025
2936021
nats sync: backend syncdocs working with proper doctype
williamstein Feb 1, 2025
bc2d855
nats auth: implement function to remove project permissions
williamstein Feb 1, 2025
a18e29f
nats: add generic pub/sub with event emitter, which I'm now using to …
williamstein Feb 1, 2025
a72862d
nats cursors -- make it work :-)
williamstein Feb 2, 2025
538188a
Merge branch 'master' into nats
williamstein Feb 2, 2025
82ac7c0
enable nats-based synctable for database changefeeds; also make the i…
williamstein Feb 2, 2025
5ea6e0c
nats: integrate hub database service; refactor and use getAll more
williamstein Feb 2, 2025
b4567d3
nats: typescript fix and reminder
williamstein Feb 2, 2025
851c7a6
nats: improve docs and initial configuration
williamstein Feb 2, 2025
02b0af2
nats: tiny bit more docs
williamstein Feb 2, 2025
937f5b8
don't recomend nats env
williamstein Feb 2, 2025
9028029
nats database changefeeds -- rewrite how they work to address several…
williamstein Feb 2, 2025
8412f2d
nats database synctable: implement a major optimization
williamstein Feb 2, 2025
090ebfc
sync editing -- commit more frequently
williamstein Feb 2, 2025
6d17cb8
nats: eliminate use of hub websocket for changefeeds... but
williamstein Feb 2, 2025
6b43eb7
nats query client: fix return format so now crm works fine :-)
williamstein Feb 2, 2025
4653cc2
nats: work in progress refactoring touch, touch_project
williamstein Feb 2, 2025
3dd81a2
nats: eliminate old touch codepath -- use new api
williamstein Feb 3, 2025
e97c18b
user_tracking: switch to nats api; at admin setting so it is disabled…
williamstein Feb 3, 2025
092bfc5
remove web browser prometheus reporting
williamstein Feb 3, 2025
5e8856e
nats/api: only use new api for managing api keys... and
williamstein Feb 3, 2025
c12c036
delete ancient deprecated code for zendesk in the app
williamstein Feb 3, 2025
197fe9a
nats: rewrite streaming LLM output to use ephemeral nats jetstreams a…
williamstein Feb 3, 2025
5875d37
nats: implement a very cool key:value store wrapper, which we're goin…
williamstein Feb 4, 2025
c5af663
nats: framework for system config -- not used yet
williamstein Feb 4, 2025
f9237d3
nats hub: add authtoken rpc
williamstein Feb 4, 2025
bb106ff
database: rewrite central log save in typescript
williamstein Feb 4, 2025
acb2a1a
nats: switch admin user impersonate to new api
williamstein Feb 4, 2025
bb57170
nats hub -- rewrite user search
williamstein Feb 4, 2025
2df7477
nats: rewrite getNames to use new api
williamstein Feb 4, 2025
fa63cde
nats: user new api for getBalance
williamstein Feb 4, 2025
21f831d
Merge branch 'master' into nats
williamstein Feb 4, 2025
867f350
oops -- metrics-recorder is of course used for more than just browser…
williamstein Feb 4, 2025
76a6610
nats: new api for create project
williamstein Feb 4, 2025
8c04d87
nats: add new api support for read/write text file to project
williamstein Feb 4, 2025
c90e4e3
nats: improve the kv a little more
williamstein Feb 4, 2025
108f3fe
nats: improve kv store even more
williamstein Feb 4, 2025
6ff85e5
fix some typescript issue with kv
williamstein Feb 5, 2025
10390fa
nats: work in progress rewriting copy path between projects...
williamstein Feb 5, 2025
e0a4c00
nats: first attempt at simple browser api.
williamstein Feb 5, 2025
c46e0c3
nats: clean up how sign in cookies are set; also set a new account_id…
williamstein Feb 5, 2025
2ef3d16
nats: fix changefeeds (they were hanging due to a refactor)
williamstein Feb 5, 2025
fcf157c
nats: make my req/reply api services be registered NATS microservices…
williamstein Feb 6, 2025
c103fd8
nats: locking down the JWT permissions rules
williamstein Feb 6, 2025
6c8c6b9
nats: fix terminal streams permissions
williamstein Feb 6, 2025
743f46d
nats auth: get rid of redundant code for specifying rules
williamstein Feb 6, 2025
e17448c
account prefs save error crashed server so fix this and make error be…
williamstein Feb 6, 2025
3e8bb44
nats: unify and improve the default connection parameters
williamstein Feb 6, 2025
9770162
nats: trying a little "eventually consistent KV" POC
williamstein Feb 6, 2025
f4579bc
nats kv: work in progress
williamstein Feb 7, 2025
8041513
nats: more work on eventually consistent key value store
williamstein Feb 7, 2025
b28442e
nats distributed key value store -- rename and document
williamstein Feb 7, 2025
eb977e3
nats: adding a stream wrapper
williamstein Feb 7, 2025
c69423e
nats stream class: much, much better
williamstein Feb 8, 2025
d4deba6
nats: create dstream = distributed eventually consistent stream class
williamstein Feb 8, 2025
6ff903b
nats: add stream limits
williamstein Feb 8, 2025
98b6ac2
nats filtered stream: implement all the limits
williamstein Feb 8, 2025
3c461b9
nats streams: support start_seq
williamstein Feb 8, 2025
18b8433
nats streams: better cache
williamstein Feb 8, 2025
bae0e05
nats: easy use of account/project streams from backend
williamstein Feb 8, 2025
7c1793e
nats stream: ability to fill in old values
williamstein Feb 8, 2025
88bde9a
nats streams: s[n] notation; new public streams (hub can write; proje…
williamstein Feb 8, 2025
017067e
nats: user friendly account/project/public kv an dkv
williamstein Feb 8, 2025
58d7066
nats: make it so our streams/kv's can have *arbitrary* names, rather …
williamstein Feb 9, 2025
fa1aff2
nats kv: make it possible to use *arbitrary strings* for keys
williamstein Feb 9, 2025
34f1457
nats: switching to new stream for terminal -- work in progress that d…
williamstein Feb 9, 2025
1f2a475
fix a circular reference issue
williamstein Feb 9, 2025
e583350
nats: new streams were hanging on startup
williamstein Feb 9, 2025
f058779
nats terminal: limit history size (in bytes)
williamstein Feb 9, 2025
e76dfca
nats auth: no longer use -terminal stream
williamstein Feb 9, 2025
21636fd
nats: implements limits for kv
williamstein Feb 9, 2025
0991640
nats dkv: implement limits; also handling of rejected changes due to …
williamstein Feb 9, 2025
fa07410
nats dstream: add reject event support
williamstein Feb 9, 2025
df98481
nats: add better time support to kv and stream
williamstein Feb 9, 2025
0a7eb65
nats: rewrite open files tracker to use new dkv
williamstein Feb 9, 2025
9cd3c07
nats: do not throttle dkv and dstream unless there are errors (e.g., …
williamstein Feb 9, 2025
f363cd0
nats: switch to using new dstream for patches table :-)
williamstein Feb 9, 2025
c1d2f6c
nats: broken (!) work in progress switching database changefeeds to n…
williamstein Feb 9, 2025
c903fa1
nats changefeeds -- fix some bugs with rewrite; this makes sense fina…
williamstein Feb 10, 2025
0874950
nats: implemented new "dko" = distributed key:object store, where whe…
williamstein Feb 10, 2025
4339bb8
switch to using new synctable based on new dko.
williamstein Feb 10, 2025
08b7302
nats: fully switched everything to my new kv/stream implementations, …
williamstein Feb 10, 2025
ac0b8ff
nats: subtle issues with deleting from non-atomic distributed changef…
williamstein Feb 11, 2025
5e30be6
messages table: don't merge in messages, since then deleting doesn't …
williamstein Feb 11, 2025
d8f25dc
nats: greatly speedup reading initial kv out of nats
williamstein Feb 11, 2025
6115ccc
nats install: improve install process, document better, newest nats-s…
williamstein Feb 11, 2025
13e61f0
nats: start unit testing; even found a bug in creating a change handler.
williamstein Feb 11, 2025
664afdf
nats dkv testing -- work in progress unit testing
williamstein Feb 11, 2025
3e61607
nats dkv -- more unit tests
williamstein Feb 11, 2025
3e08025
nats: unit testing 3-way merge conflict implementation
williamstein Feb 11, 2025
2e1b556
nats kv -- more unit tests, especially involving 3-way merge
williamstein Feb 11, 2025
e124221
nats: fix some bugs revealed by testing and caused by testing
williamstein Feb 12, 2025
b553711
nats: fix major issue with hangs at scale (due to lack of auth)
williamstein Feb 12, 2025
00a3737
nats database synctable -- free synctables (avoid eventemitter leaks,…
williamstein Feb 12, 2025
01b5fc6
nats: solve the req/reply "inbox security" issue for users via inbox …
williamstein Feb 12, 2025
f4cdd2a
database user tracker: properly fix subtle bug that would cause issue…
williamstein Feb 12, 2025
195d54a
Merge branch 'master' into nats
williamstein Feb 12, 2025
29f1f5b
use test namespace for testing nats kv and streams.
williamstein Feb 12, 2025
26a7221
nats dstream: fix some bugs and create some unit tests
williamstein Feb 12, 2025
4994b84
nats dstream: add unit tests and fix bugs
williamstein Feb 13, 2025
e4c10ec
nats: adjust parallel param and make comment in unit tests about speed
williamstein Feb 13, 2025
825a16c
nats dkv: better testing null/undefined values (and fix bug testing r…
williamstein Feb 13, 2025
f3c53f6
nats: fix the @cocalc/sync test suite by not making *it* use nats
williamstein Feb 13, 2025
1e60bd4
fixing unit tests
williamstein Feb 13, 2025
d426771
delete the exec shell code api test
williamstein Feb 13, 2025
ae89578
admin impersonation: fix some bugs in my new implementation
williamstein Feb 13, 2025
c6961fc
nats open file data: improving it
williamstein Feb 13, 2025
9ee9323
nats sync: fix opening non-string first time
williamstein Feb 13, 2025
139bb21
nats: unit test open-files
williamstein Feb 13, 2025
a6ae9c4
nats sync objects: mostly improving caching and testing
williamstein Feb 13, 2025
db264ec
nats + trimetravel -- make timetravel close syncdoc it opens
williamstein Feb 14, 2025
6f30fa5
nats: create nice abstraction for services
williamstein Feb 14, 2025
b8bdad4
nats -- active jupyter
williamstein Feb 14, 2025
aae1da6
nats: ipywidgets support
williamstein Feb 14, 2025
bbed478
nats: wire up code formatter
williamstein Feb 14, 2025
e6b638f
nats: better call error messages
williamstein Feb 14, 2025
eb0d1b4
nats service: add a typed option
williamstein Feb 14, 2025
12957dd
switch jupyter to use new typed api
williamstein Feb 14, 2025
0e32a10
jupyter api: slightly better typing
williamstein Feb 14, 2025
8691b75
nats: auth -- fix service permissions
williamstein Feb 14, 2025
8159cae
nats sync: fix issue with changefeeds not working
williamstein Feb 15, 2025
a3bc1ea
nats: sage worksheets
williamstein Feb 15, 2025
9deb844
nats sync: expire ipywidgets
williamstein Feb 15, 2025
92ad19d
nats terminal: fixing some issues with initial load and sizing
williamstein Feb 15, 2025
d80b55d
nats: rewriting more terminal functionality
williamstein Feb 15, 2025
75801e3
nats: different approach to typed service RPC with terminal
williamstein Feb 15, 2025
5df9575
nats: yet another attempt at nice typed RPC api microservices
williamstein Feb 15, 2025
5ccf778
nats jupyter api: more typing
williamstein Feb 15, 2025
0e932d1
nats terminal: properly implementing browser side
williamstein Feb 16, 2025
f08bc33
terminal: mostly implement "kick"
williamstein Feb 16, 2025
98b24b9
nats services: incorporate stats/info/ping/waitFor
williamstein Feb 16, 2025
7b215d6
nats: improve terminal startup robustness
williamstein Feb 16, 2025
16b8e0e
nats terminal: implement 'kick'
williamstein Feb 16, 2025
c61fcb4
nats terminal: deleting old code, mostly
williamstein Feb 16, 2025
b636af3
nats: make initial load of stream much faster and always load it all
williamstein Feb 16, 2025
9124f53
dstream -- support optional typing
williamstein Feb 16, 2025
586dfc3
add typing support to DKO, DKV, KV, DStream, Stream
williamstein Feb 16, 2025
cdf0f1c
nats: work in progress rewriting listings
williamstein Feb 17, 2025
3a2c32b
nats: implementing new directory listings watcher
williamstein Feb 17, 2025
2e9c543
nats listings: packaged client
williamstein Feb 17, 2025
0338401
nats listings -- start integrating with frontend
williamstein Feb 17, 2025
f1dbea2
make 'cc.current()' better to aid in debugability of cocalc
williamstein Feb 17, 2025
b16a35c
nats: work in progress on revamping directory listings state
williamstein Feb 17, 2025
708fe11
open-files: dealing with deleted files
williamstein Feb 17, 2025
1b760e4
nats: add monitoring to kv store
williamstein Feb 18, 2025
eec42ba
nats kv: confirmed that my monitor works
williamstein Feb 18, 2025
ca7ea3c
nats-based delete file management: deal with some edge cases exposed …
williamstein Feb 18, 2025
4214fec
nats file deletion handling: work in progress
williamstein Feb 18, 2025
cd3a551
nats: handling deleted files
williamstein Feb 18, 2025
b7c2ca2
nats: starting project and initial listing -- improve
williamstein Feb 18, 2025
d1bb47e
nats compute servers: change frontend to use new nats based manager
williamstein Feb 19, 2025
2f539f0
nats compute servers -- make project open-files use the new manager i…
williamstein Feb 19, 2025
921b1aa
nats compute servers: improve file and terminal switching
williamstein Feb 19, 2025
f2dfc8e
nats: workaround typescript issue
williamstein Feb 19, 2025
ed4433d
nats project connection: automatically reconnect until success
williamstein Feb 19, 2025
9f95980
nats: fix project auth
williamstein Feb 19, 2025
4738cb9
nats: implement time sync using nats jetstream
williamstein Feb 19, 2025
ee4d657
nats time and open files: use sync'd time explicitly
williamstein Feb 19, 2025
b5e6bc5
nats: change delete in open-files so can properly resolve merge confl…
williamstein Feb 19, 2025
03ca5bc
nats open files: track exactly which backend has file opened and when
williamstein Feb 19, 2025
4bbd937
nats: start wokr on streaming file get service
williamstein Feb 19, 2025
2f038d0
nats: implement async generator to read file from compute server or p…
williamstein Feb 20, 2025
d3a8f84
nats: raw files -- work in progress
williamstein Feb 20, 2025
352961a
nats streaming file download: the project/compute server part seems done
williamstein Feb 20, 2025
fef2012
nats file download: more integration throughout the system
williamstein Feb 20, 2025
70e75a9
nats file read -- add auth
williamstein Feb 20, 2025
1465dd4
"raw url" --> "files url" for download -- refactor code so url always…
williamstein Feb 20, 2025
ec94533
nats: create streaming file write service (no testing)
williamstein Feb 21, 2025
5be29e1
nats file write: add example and fix the one (and only?) mistake
williamstein Feb 21, 2025
c2b84be
nats unit tests: reorg sync; write new tests for time and writeFile
williamstein Feb 21, 2025
1e2a704
nats: write unit tests of streaming reads
williamstein Feb 21, 2025
7917aee
nats: fix some unit tests and add some more docs
williamstein Feb 21, 2025
2bc2c08
nats file upload: starting work integrating this with hub (work in pr…
williamstein Feb 21, 2025
be306d4
add env variable to not run nextjs
williamstein Feb 21, 2025
68cbe8c
nats upload: more work in progress
williamstein Feb 21, 2025
65ebf25
nats hub file upload: this approach sucks
williamstein Feb 21, 2025
3d02486
nats file upload: this works (but is still not pretty)
williamstein Feb 21, 2025
4b142f3
nats hub upload: I think this is the hard part, done.
williamstein Feb 21, 2025
91c36da
project: completely remove raw file server! (major security enhanceme…
williamstein Feb 22, 2025
c6aadf8
nats upload: better error handling
williamstein Feb 22, 2025
f9a0a52
nats upload: support directory trees properly
williamstein Feb 22, 2025
35d2664
nats upload: automatically start upload service in project
williamstein Feb 22, 2025
16eddb4
nats upload: show error when there's only one chunk
williamstein Feb 22, 2025
8593e6d
llm: rewrite to use multiresponse instead of jetstream (work in progr…
williamstein Feb 22, 2025
1e9b91e
llm integration: get it working end-to-end with nats multi response
williamstein Feb 23, 2025
566d595
sync: make ephemeral syncstring and testing more sensibly not use nats
williamstein Feb 23, 2025
c4f4be3
tiny comments while looking at some of the project status code
williamstein Feb 23, 2025
d7c6a19
jupyter/nats: fix "close and halt" not working
williamstein Feb 23, 2025
8f0dcd6
jupyter api: rewrite all client code so it gets type checked with typ…
williamstein Feb 23, 2025
af2ef40
nats db query: convert timestamps to Date objects client side (due to…
williamstein Feb 23, 2025
e6821e6
nats: integrate with connection indicator and modal
williamstein Feb 23, 2025
17e4b2f
fix fallout of Date processing
williamstein Feb 23, 2025
6b85edf
fix cursor bug with Jupyter which was -- amusingly -- only visible wh…
williamstein Feb 23, 2025
dbfd905
nats sync: make inventories for our small distributed eventually cons…
williamstein Feb 24, 2025
e0dad23
nats sync inventory: implement dkv part
williamstein Feb 24, 2025
41e41fe
nats inventory: fix little issues
williamstein Feb 24, 2025
bd07b0d
nats: implement inventory for dstream's
williamstein Feb 24, 2025
6452b7a
test mode: disable nats inventory by default; also express frustratio…
williamstein Feb 24, 2025
2a3306c
nats: add desc to inventory
williamstein Feb 24, 2025
98a27e7
nats inventory: make it better
williamstein Feb 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
299 changes: 299 additions & 0 deletions docs/nats/devlog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
# NATS Development and Integration Log

## [x] Goal: nats from nodejs

- start a nats server in cocalc\-docker
- connect from nats cli outside docker
- connect to it from the nodejs client over a websocket

```sh
nats-server -p 5004

nats context save --select --server nats://localhost:5004 nats

nats sub '>'
```

Millions of messages a second works \-\- and you can run like 5x of these at once without saturating nats\-server.

```js
import { connect, StringCodec } from "nats";
const nc = await connect({ port: 5004 });
console.log(`connected to ${nc.getServer()}`);
const sc = StringCodec();

const t0 = Date.now();
for (let i = 0; i < 1000000; i++) {
nc.publish("hello", sc.encode("world"));
}
await nc.drain();
console.log(Date.now() - t0);
```

That was connecting over TCP. Now can we connect via websocket?

## [x] Goal: Websocket from browser

First need to start a nats **websocket** server instead on port 5004:

[https://nats.io/blog/getting\-started\-nats\-ws/](https://nats.io/blog/getting-started-nats-ws/)

```sh
nats context save --select --server ws://localhost:5004 ws
~/nats/nats.js/lib$ nats context select ws
NATS Configuration Context "ws"

Server URLs: ws://localhost:5004
Path: /projects/3fa218e5-7196-4020-8b30-e2127847cc4f/.config/nats/context/ws.json

~/nats/nats.js/lib$ nats pub foo bar
21:24:53 Published 3 bytes to "foo"
~/nats/nats.js/lib$
```

##

- their no\-framework html example DOES work for me!
- [https://localhost:4043/projects/3fa218e5\-7196\-4020\-8b30\-e2127847cc4f/files/nats/nats.js/lib/ws.html](https://localhost:4043/projects/3fa218e5-7196-4020-8b30-e2127847cc4f/files/nats/nats.js/lib/ws.html)
- It takes about 1\-2 seconds to send **one million messages** from browser outside docker to what is running inside there!

## [x] Goal: actually do something useful

- nats server
- browser connects via websocket port 5004
- nodejs hub connects via tcp
- hub answers a ping or something else from the browser...

This worked perfectly with no difficulty. It's very fast and flexible and robust.

Reconnects work, etc.

## [x] Goal: proxying

- nats server with websocket listening on localhost:5004
- proxy it via node\-proxy in the hub to localhost:4043/nats
- as above

This totally worked!

Everything is working that I try?!

Maybe NATS totally kicks ass.

## [x] Goal: do something actually useful.

- authentication: is there a way to too who the user who made the websocket connection is?
- worry about this **later** \- obviously possible and not needed for a POC
- let's try to make `write_text_file_to_project` also be possible via nats.
- OK, made some of api/v2 usable. Obviously this is really minimal POC.

## [x] GOAL: do something involving the project

The most interesting use case for nats/jetsteam is timetravel collab editing, where this is all a VERY natural fit.

But for now, let's just do _something_ at all.

This worked - I did project exec with subject projects.{project_id}.api

## [x] Goal: Queue group for hub api

- change this to be a queue group and test by starting a few servers at once

## [x] Goal: Auth Strategy that is meaningful

Creating a creds file that encodes a JWT that says what you can publish and subscribe to, then authenticating with that works.

- make it so user with account_id can publish to hub.api.{account_id} makes it so we know the account_id automatically by virtue of what was published to. This works.

## [x] Goal: Solve Critical Auth Problems

Now need to solve two problems:

- [x] GOAL: set the creds for a browser client in a secure http cookie, so the browser can't directly access it

I finally figured this out after WASTING a lot of time with stupid AI misleading me and trying actively to get me to write very stupid insecure code as a lazy workaround. AI really is very, very dangerous... The trick was to read the docs repeatedly, increase logging a lot, and \-\- most imporantly \-\- read the relevant Go source code of NATS itself. The answer is to modify the JWT so that it explicitly has bearer set: `nsc edit user wstein --bearer`

This makes it so the server doesn't check the signature of the JWT against the _user_ . Putting exactly the JWT token string in the cookie then works because "bearer" literally tells the backend server not to do the signature check. I think this is secure and the right approach because the server checks that the JWT is valid using the account and operator signatures.

**WAIT!** Using signing keys [https://docs.nats.io/using\-nats/nats\-tools/nsc/signing_keys](https://docs.nats.io/using-nats/nats-tools/nsc/signing_keys) \(and https://youtu.be/KmGtnFxHnVA?si=0uvLMBTJ5TUpem4O \) is VASTLY superior. There's just one JWT issued to each user, and we make a server\-side\-only JWT for their account that has everything. The user never has to reconnect or change their JWT. We can adjust the subject on the fly to account for running projects \(or collaboration changes\) at any time server side. Also the size limits go away, so we don't have to compress project_id's \(probably\).

## Goal: Implement Auth Solution for Browsers

- [x] automate creation of creds for browser clients, i.e., what we just did with the nsc tool manually
-

---

This is my top priority goal for NOW!

What's the plan?

Need to figure out how to do all the nsc stuff from javascript, storing results in the database?

- Question: how do we manage creating signing keys and users from nodejs? Answer: clear from many sources that we must use the nsc CLI tool via subprocess calls. Seems fine to me.
- [x] When a user signs in, we check for their JWT in the database. If it is there, set the cookie. If not, create the signing key and JWT for them, save in database, and set the cookie.
- [x] update nats\-server resolver state after modifying signing cookie's subjects configuration.

```
nsc edit operator --account-jwt-server-url nats://localhost:4222
```

Now I can do `nsc push` and it just works.

[x] TODO: when signing out, need to delete the jwt cookie or dangerous private info leaks... and also new info not set properly.

- [x] similar creds for projects, I.e., access to a project means you can publish to `projects.{project_id}.>` Also, projects should have access to something under hub.

## [x] Goal: Auth for Projects

Using an env variable I got a basic useful thing up and running.

---

Some thoughts about project auth security:

- [ ] when collaborators on a project leave maybe we change JWT? Otherwise, in theory any user of a project can probably somehow get access to the project's JWT \(it's in memory at least\) and still act as the project. Changing JWT requires reconnect. This could be "for later", since even now we don't have this level of security!
- [ ] restarting project could change JWT. That's like the current project's secret token being changed.

## [ ] Goal: nats-server automation of creation and configuration of system account, operator, etc.

- This looks helpful: https://www.synadia.com/newsletter/nats-weekly-27/
- NOT DONE YET

## [x] Goal: Terminal! Something complicated involving the project which is NOT just request/response

- Implementing terminals goes beyond request/response.
- It could also leverage jetstream if we want for state (?).
- Multiple connected client

Project/compute server sends terminal output to

project.{project_id}.terminal.{sha1(path)}

Anyone who can read project gets to see this.

Browser sends terminal input to

project.{project_id}.{group}.{account_id}.terminal.{sha1(path)}

API calls:

- to start terminal
- to get history (move to jetstream?)

If I can get this to work, then collaborative editing and everything else is basically the same (just more details).

## [x] Goal: Terminal! #now

Make it so an actual terminal works, i.e., UI integration.

## [x] Goal: Terminal JetStream state

Use Jetstream to store messages from terminal, so user can reconnect without loss. !? This is very interesting...

First problem -- we used the system account SYS for all our users; however,
SYS can't use jetstreams, as explained here https://github.com/nats-io/nats-server/discussions/6033

Let's redo *everything* with a new account called "cocalc".

```sh
~/nats$ nsc create account --name=cocalc
[ OK ] generated and stored account key "AD4G6R62BDDQUSCJVLZNA7ES7R3A6DWXLYUWGZV74EJ2S6VBC7DQVM3I"
[ OK ] added account "cocalc"
~/nats$ nats context save admin --creds=/projects/3fa218e5-7196-4020-8b30-e2127847cc4f/.local/share/nats/nsc/keys/creds/MyOperator/cocalc/admin.creds
~/nats$ nsc edit account cocalc --js-enable 1
~/nats$ nsc push -a cocalc
```

```js
// making the stream for ALL terminal activity
await jsm.streams.add({ name: 'project-81e0c408-ac65-4114-bad5-5f4b6539bd0e-terminal', subjects: ['project.81e0c408-ac65-4114-bad5-5f4b6539bd0e.terminal.>'] });

// making a consumer for just one subject (e.g., one terminal frame)
z = await jsm.consumers.add('project-81e0c408-ac65-4114-bad5-5f4b6539bd0e-terminal',{name:'9149af7632942a94ea13877188153bd8bf2ace57',filter:['project.81e0c408-ac65-4114-bad5-5f4b6539bd0e.terminal.9149af7632942a94ea13877188153bd8bf2ace57']})
c = await js.consumers.get('project-81e0c408-ac65-4114-bad5-5f4b6539bd0e-terminal', '9149af7632942a94ea13877188153bd8bf2ace57')
for await (const m of await c.consume()) { console.log(cc.client.nats_client.jc.decode(m.data))}
```

NOTE!!! The above consumer is ephemeral -- it disappears if we don't grab it via c within a few seconds!!!! https://docs.nats.io/using-nats/developer/develop_jetstream/consumers

## [ ] Goal: Jetstream permissions

- [x] project should set up the stream for capturing terminal outputs.
- [x] delete old messages with a given subject. `nats stream purge project-81e0c408-ac65-4114-bad5-5f4b6539bd0e-terminal --seq=7000`
- there is a setting max\_msgs\_per\_subject on a stream, so **we just set that and are done!** Gees. It is too easy.
- [x] handle the other messages like resize
- [x] need to move those other messages to a different subject that isn't part of the stream!!
- [ ] permissions for jetstream usage and access
- [ ] use non\-json for the data....
- [ ] refactor code so basic parameters \(e.g., subject names, etc.\) are defined in one place that can be imported in both the frontend and backend.
- [ ] font size keyboard shortcut
- [ ] need a better algorithm for sizing since we don't know when a user disconnects!
- when one user proposes a size, all other clients get asked their current size and only those that respond matter. how to do this?

## [ ] Goal: Basic Collab Document Editing

Plan.

- [x] Use a kv store hosted on nats to trac syncstring objects as before. This means anybody can participate \(browser, compute server, project\) without any need to contact the database, hence eliminating all proxying!

[x] Next Goal \- collaborative file editing \-\- some sort of "proof of concept"! This requires implementing the "ordered patches list" but on jetstream. Similar to the nats SyncTable I wrote yesterday, except will use jetstream directly, since it is an event stream, after all.

- [x] synctable\-stream: change to one big stream for the whole project but **consume** a specific subject in that stream?

[ ] cursors \- an ephemeral table

---

- [ ] Subject For Particular File: `project.${project_id}.patches.${sha1(path)}`
- [ ] Stream: Records everything with this subject `project.${project_id}.patches`
- [ ] It would be very nice if we can use the server assigned timestamps.... but probably not
- [ ] For transitioning and de\-archiving, there must be a way to do this, since they have a backup/restore process

## [ ] Goal: PostgreSQL Changefeed Synctable

This is critical to solve. This sucks now. This is key to eliminating "hub\-websocket". This might be very easy. Here's the plan:

- [x] make a request/response listener that listens on hub.account.{account\_id} and hub.db.project.{project\_id} for a db query.
- [x] if changes is false, just responds with the result of the query.
- [ ] if changes is true, get kv store k named `account-{account_id}` or `project-{project_id}` \(which can be used by project or compute server\).
- let id be the sha1 hash of the query \(and options\)
- k.id.update is less than X seconds ago, do nothing... it's already being updated by another server.
- do the query to the database \(with changes true\)
- write the results into k under k.id.data.key = value.
- keep watching for changes so long as k.id.interest is at most n\*X seconds ago.
- Also set k.id.update to now.
- return id
- [ ] another message to `hub.db.{account_id}` which contains a list of id's.
- When get this one, update k.id.interest to now for each of the id's.

With the above algorithm, it should be very easy to reimplement the client side of SyncTable. Moreover, there are many advantages:

- For a fixed account\_id or project\-id, there's no extra work at all for 1 versus 100 of them. I.e., this is great for opening a bunch of distinct browser windows.
- If you refresh your browser, everything stays stable \-\- nothing changes at all and you instantly have your data. Same if the network drops and resumes.
- When implementing our new synctable, we can immediately start with the possibly stale data from the last time it was active, then update it to the correct data. Thus even if everything but NATS is done/unavailable, the experience would be much better. It's like "local first", but somehow "network mesh first". With a leaf node it would literally be local first.

---

This is working well!

TODO:

- [x] build full proof of concept SyncTable on top of my current implementation of synctablekvatomic, to _make sure it is sufficient_
- this worked and wasn't too difficult

THEN do the following to make it robust and scalable

- [ ] store in nats which servers are actively managing which synctables
- [ ] store in nats the client interest data, instead of storing it in memory in a server? i.e., instead of client making an api call, they could instead just update a kv and say "i am interested in this changefeed". This approach would make everything just keep working easily even as servers scale up/down/restart.

---

## [ ] Goal: Terminal and **compute server**

Another thing to do for compute servers:

- use jetstream and KV to agree on _who_ is running the terminal?

This is critical to see how easily we can support compute servers using nats + jetstream.

24 changes: 14 additions & 10 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# How to Build and Run CoCalc

Updated: **Jan 2023**
**Updated: Feb 2025**

CoCalc is a pretty large and complicated project, and it will only work with the current standard LTS release of node.js \( at least 16.8.x\) and a recent version of [pnpm](https://pnpm.io/).
CoCalc is a pretty large and complicated project, and it will only work with the current standard LTS release of node.js \( at least 18.17.1\) and a recent version of [pnpm](https://pnpm.io/). Also, you will need a LOT of RAM, a minimum of 16 GB. **It's very painful to do development with less than 32 GB of RAM.**

**Node.js and NPM Version Requirements:**

- You must be using Node version 16.8.x or newer. **CoCalc will definitely NOT work with any older version!** In a [CoCalc.com](http://CoCalc.com) project, you can put this in `~/.bashrc` to get a valid node version:
- You must be using Node version 18.17.1 or newer. **CoCalc will definitely NOT work with any older version!** In a [CoCalc.com](http://CoCalc.com) project, you can put this in `~/.bashrc` to get a valid node version:

```sh
. /cocalc/nvm/nvm.sh
Expand Down Expand Up @@ -56,22 +56,25 @@ To install required dependencies, run
hand, you prefer that development packages be installed globally, you can jump directly to the above `pip install`
command outside the context of a virtual environment.

## Initial Build
## Build and Start

Launch the install and build **for doing development:**
Launch the install and build **for doing development.**

If you export the PORT environment variable, that determines what port everything listens on. This determines subtle things about configuration, so do this once and for all in a consistent way.

**Note**: If you installed `pnpm` locally (instead of globally), simply run `npm run` in place of `pnpm` to execute
these commands via [NPM run scripts](https://docs.npmjs.com/cli/v10/using-npm/scripts).

```sh
~/cocalc/src$ pnpm make-dev
~/cocalc/src$ pnpm build-dev
```

This will do `pnpm install` for all packages, and also build the typescript/coffeescript, and anything else into a dist directory for each module. Once `pnpm make` finishes successfully, you can start using CoCalc by starting the database and the backend hub in two separate terminals.
This will do `pnpm install` for all packages, and also build the typescript/coffeescript, and anything else into a dist directory for each module. Once `pnpm build-dev` finishes successfully, you can start using CoCalc by starting the database, nats server and the backend hub in three terminals. \(Note that 'pnpm nats\-server' will download, install and configure NATS automatically.\) You can start the database, nats\-server and hub in any order.

```sh
~/cocalc/src$ pnpm database # in one terminal
~/cocalc/src$ pnpm hub # in another terminal
~/cocalc/src$ pnpm database # in one terminal
~/cocalc/src$ pnpm nats-server # in one terminal
~/cocalc/src$ pnpm hub # in another terminal
```

The hub will send minimal logging to stdout, and the rest to `data/logs/log`.
Expand All @@ -95,7 +98,7 @@ The main \(only?\) difference is that static and next webpack builds are created
If necessary, you can delete all the `node_modules` and `dist` directories in all packages and start over as follows:

```sh
~/cocalc/src$ pnpm clean && pnpm make-dev
~/cocalc/src$ pnpm clean && pnpm build-dev
```

## Doing Development
Expand Down Expand Up @@ -218,3 +221,4 @@ Regarding VS Code, the relevant settings can be found by searching for "autosave
There's some `@cocalc/` packages at [NPMJS.com](http://NPMJS.com). However, _**we're no longer using**_
_**them in any way**_, and don't plan to publish anything new unless there
is a compelling use case.

5 changes: 4 additions & 1 deletion src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
"version-check": "pip3 install typing_extensions mypy || pip3 install --break-system-packages typing_extensions mypy && ./workspaces.py version-check && mypy scripts/check_npm_packages.py",
"test-parallel": "unset DEBUG && pnpm run version-check && cd packages && pnpm run -r --parallel test",
"test": "unset DEBUG && pnpm run version-check && cd packages && pnpm run -r test",
"prettier-all": "cd packages/"
"prettier-all": "cd packages/",
"nats-server": "cd ${COCALC_ROOT:=$INIT_CWD}/packages/backend && node -e \"require('@cocalc/backend/nats/conf').main()\" && cd ${COCALC_ROOT:=$INIT_CWD}/data/nats && ./bin/nats-server -c server.conf",
"nats-server-verbose": "cd ${COCALC_ROOT:=$INIT_CWD}/packages/backend && node -e \"require('@cocalc/backend/nats/conf').main()\" && cd ${COCALC_ROOT:=$INIT_CWD}/data/nats && ./bin/nats-server -DV -c server.conf",
"nats-cli": "echo; echo '# Use CoCalc config of NATS (nats and nsc) via this subshell:'; echo; echo \"export XDG_DATA_HOME=${COCALC_ROOT:=$INIT_CWD}/data\"; echo \"export XDG_CONFIG_HOME=${COCALC_ROOT:=$INIT_CWD}/data\"; echo \"export PATH=${COCALC_ROOT:=$INIT_CWD}/data/nats/bin:\\$PATH\"; echo; echo; XDG_DATA_HOME=${COCALC_ROOT:=$INIT_CWD}/data XDG_CONFIG_HOME=${COCALC_ROOT:=$INIT_CWD}/data PATH=${COCALC_ROOT:=$INIT_CWD}/data/nats/bin:$PATH bash"
},
"repository": {
"type": "git",
Expand Down
Loading